首页 > 解决方案 > 10000次迭代后如何在循环中设置浮点值的精度,当不工作?

问题描述

我想打印一个带有嵌套循环的二维数组,但是经过几千次迭代后,值的精度不正确。(我不想将整个矩阵保存在内存中,因为我想在一行中运行几百万个值。)

我尝试了一些精度设置的方法,但这些都不起作用。例如,我自己的精度设置器函数以及字符串转换。

#include <iostream>
#include <iomanip>
#include <string>
#include <stdlib.h>
#include <cmath>


using namespace std;

void printNumbers( float minX1, float maxX1, float stepX1,
                    float minX2, float maxX2, float stepX2);

float setPrecisionOfValue (float x);

int main()
{


    // minX1, maxX1, stepX1, minX2, maxX2, stepX2
    printNumbers(-512,512,0.2, -512,512,0.2);

    return 0;
}

void printNumbers( float minX1, float maxX1, float stepX1,
                    float minX2, float maxX2, float stepX2)
{
    // stepX1 = setPrecisionOfValue( stepX1 );
    // stepX2 = setPrecisionOfValue( stepX2 );

    for (float x1 = minX1; x1<=maxX1; x1+=stepX1){
        for (float x2 = minX2; x2<=maxX2; x2+=stepX2 ){

            cout << setprecision(5);

            // cout << "stepx1: " << stepX1 << "\t";
            // cout << "stepx2: " << stepX2 << "\t";

        // x1 = setPrecisionOfValue( x1 );
            // x2 = setPrecisionOfValue( x2 );
            cout  << "x1: " << x1 << "\t" ;
            cout  << "x1: " << x2 << "\t" ;
            cout << setprecision(15);
            std:: fixed;
            cout << "x1/x2: " << (double)x1/x2 ;
            cout << endl;
        }
    }

    cout << "Done!"<< endl;

}


float setPrecisionOfValue ( float x){

    double n = 1.0; //Number of float decimals. At the 0.2 this number is 1.


    if( x<0 ){
        return (float)((int)ceil((x*pow(1000,n)))) / (float)pow(1000,n);
    }
    else{
        return (float)((int)floor((x*pow(1000,n)))) / (float)pow(1000,n);
    }


}

结果:

x1: -512        x1: -512        x1/x2: 1
x1: -512        x1: -511.8      x1/x2: 1.00039080150801
x1: -512        x1: -511.6      x1/x2: 1.00078190858708
x1: -512        x1: -511.4      x1/x2: 1.00117332159574
x1: -512        x1: -511.2      x1/x2: 1.00156504089308
x1: -512        x1: -511        x1/x2: 1.00195706683876
x1: -512        x1: -510.8      x1/x2: 1.002349399793
x1: -512        x1: -510.6      x1/x2: 1.00274204011658
...
...
x1: -511.8      x1: 23.013      x1/x2: -22.23972619827
x1: -511.8      x1: 23.213      x1/x2: -22.0481100153317
x1: -511.8      x1: 23.413      x1/x2: -21.8597675340684
x1: -511.8      x1: 23.613      x1/x2: -21.6746155698405
x1: -511.8      x1: 23.813      x1/x2: -21.4925737326294
x1: -511.8      x1: 24.013      x1/x2: -21.3135643106571
x1: -511.8      x1: 24.213      x1/x2: -21.1375121597735
x1: -511.8      x1: 24.413      x1/x2: -20.9643445982809
x1: -511.8      x1: 24.613      x1/x2: -20.7939913068863
x1: -511.8      x1: 24.813      x1/x2: -20.626384233492
...

当我的步长为 0.2 时,我如何获得这些值?我该如何解决?

标签: c++precision

解决方案


float 并没有完全保持它看起来的值。如果可能,请始终使用整数。

例如,改为使用

f += 0.2;
cout << f;
use
//outside of the loop:
n = (int)(f * 10); 
//inside of the loop:
n += 2;
cout << ((float)n / 10.0);

你不会再看到那些精度损失了。


推荐阅读