-1

I'd like to print a two dimensional array with nested loops, but after a few thousand iteration the precision of the values are not correct. (I don't want to hold the whole matrix in the memory, because I'd like to run with a few million values in one row.)

I tried some method of the precision setting, but these aren't worked. For example the , my own precision setter function and also the string converting.

#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);
    }


}

The results:

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
...

When my step is 0.2, then how I get these values? How can I fix it?

vizvezetek
  • 51
  • 4
  • 1
    Possible duplicate of [Is floating point math broken?](https://stackoverflow.com/questions/588004/is-floating-point-math-broken) - Do not use floats as loop variables. – Quimby Apr 14 '19 at 20:34
  • 1
    `for (float x1 = minX1; x1<=maxX1; x1+=stepX1){for (float x2 = minX2; x2<=maxX2; x2+=stepX2 ){` -- Don't do this -- use integer-based loop variables. If you know exactly how many times to loop, then specify that number of times by using integers. Within the loop, that is where you use floating point. – PaulMcKenzie Apr 14 '19 at 20:37

1 Answers1

0

float does not hold the value exactly it looks like. If possible, always use integer.

For example, instead use

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);

You will not see those precision losing again.

Tony
  • 632
  • 1
  • 4
  • 18