1

I'm using flex and bison to read in a file that has text but also floating point numbers. Everything seems to be working fine, except that I've noticed that it sometimes changes the values of the numbers. For example,

-4.036 is (sometimes) becoming -4.0359998, and 
-3.92  is (sometimes) becoming -3.9200001

The .l file is using the lines

static float fvalue ;

sscanf(specctra_dsn_file_yytext, "%f", &fvalue) ;

The values pass through the yacc parser and arrive at my own .cpp file as floats with the values described. Not all of the values are changed, and even the same value is changed in some occurrences, and unchanged in others.

Please let me know if I should add more information.

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
ees
  • 335
  • 1
  • 2
  • 11

1 Answers1

1

float cannot represent every number. It is typically 32-bit and so is limited to at most 232 different numbers. -4.036 and -3.92 are not in that set on your platform.

<float> is typically encoded using IEEE 754 single-precision binary floating-point format: binary32 and rarely encodes fractional decimal values exactly. When assigning values like "-3.92", the actual values saved will be one close to that, but maybe not exact. IOWs, the conversion of -3.92 to float was not exact had it been done by assignment or sscanf().

float x1 = -3.92;
// float has an exact value of -3.9200000762939453125
// View @ 6 significant digits -3.92000
// OP reported                 -3.9200001

float x2 = -4.036;
// float has an exact value of -4.035999774932861328125
// View @ 6 significant digits -4.03600
// OP reported                 -4.0359998

Printing these values to beyond a certain number of significant decimal digits (typically 6 for float) can be expected to not match the original assignment. See Printf width specifier to maintain precision of floating-point value for a deeper C post.


OP could lower expectations of how many digits will match. Alternatively could use double and then only see this problem when typically more than 15 significant decimal digits are viewed.

Community
  • 1
  • 1
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256