-2

I have a quirky problem where if I input say 720.60 into

sscanf("%f", &amount);

where amount is of type float, the value in the variable changes to 720.59967.

How can I bypass this and prevent it from changing my value?

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
harshalizee
  • 129
  • 1
  • 3
  • 12

3 Answers3

1

You can print fewer digits, or use double. A single precision IEEE-754 float value has a 23 bit mantissa, which means it has about 7 decimal digits of precision. The value you see is as close as it can get: there is no float value closer to 720.60 than 720.59967.

In fact, the exact values of the two float value closest to 720.60 are:

720.5999755859375      (slightly less than 720.60)
720.60003662109375     (slightly more than 720.60)
Joni
  • 108,737
  • 14
  • 143
  • 193
  • Any workarounds that you would suggest in handling such data, where I don't care about digits after two decimal places. – harshalizee Sep 13 '13 at 08:29
  • If you only want two digits after the dot: `printf(".2f", amount)` – Joni Sep 13 '13 at 08:31
  • I know. But, for some reason, the format specifier of ".2f" does not work with sscanf. I need it to scan from a file input to be read into a float variable. Any ideas? – harshalizee Sep 13 '13 at 08:57
  • You're already reading the value correctly and with as much precision as the data type supports. What are you asking exactly? – Joni Sep 13 '13 at 09:06
  • While scanning from a file, I'm currently copying it into a float. When this value is used in computations, I get a difference of about 0.01 as I need to keep the precision to two decimal values. – harshalizee Sep 13 '13 at 09:20
  • Use `double` then, higher precision diminishes the errors so that the rounding errors don't accumulate to 0.01 quite as fast. – Joni Sep 13 '13 at 11:24
0

You cannot do that. It is precision problem, i.e. the floating point format used in C cannot represent 720.60 exactly. You can try double type for amount, that will increase your precision but still you will not get exact value.

See this link for more discussion.

Community
  • 1
  • 1
0xF1
  • 6,046
  • 2
  • 27
  • 50
0

There is an alternative to using floating point if you need a fixed number of digits after the decimal point, such as 2.

Split the input string at the ".", and treat "720.60" as two integers, 720 and 60. Multiply 720 by 100 and add 60, getting 72060. Do all your arithmetic in terms of integer numbers of hundredths. To display, print x/100 and x%100, separated by a decimal point with the second number printed as two digits with a possible leading zero.

If you prefer to work in a floating point type, double is much more precise than float. The closest float to 720.60 is 720.5999755859375. The closest double is 720.6000000000000227373675443232059478759765625. Both would round to "720.60" if printed with only two digits after the decimal point, but rounding error can build as you do arithmetic.

Patricia Shanahan
  • 25,849
  • 4
  • 38
  • 75