1

https://stackoverflow.com/questions/25224947/why-is-the-intpart-output-of-modf-forced-to-be-a-double?noredirect=1#comment39291449_25224947

Can I use double instead of float

Based on this discussion (and others) float's (and doubles) are inherently unreliable because of the IEEE encoding. I am assuming this is why we were advised to convert to int? From my research it seems that doubles (which is a form of float) can be precise enough.

I'm confused.

1 Answer 1

2

A float (or a double) is imprecise simply because there are not enough digits in binary to represent any number with recurring decimals (well, binary decimals).

Let's say you wanted to display 1/10. In decimal notation, that's 0.10 and is exact. But on the computer, that is stored in binary, and "one tenth" in binary is a recurring number.

If you were to try to print one-tenth to 30 places:

float test = 1.0/10.0;
printf("%.30f", test);

You would get: 0.100000001490116119384765625000

A float value has 32 bits to work with:

  • 1 bit to hold the sign
  • 8 bits to hold the offset exponent ( which is the exponent + 127)
  • and 23 bits to hold the significant digits

So, in the case of decimal value 0.1, it is represented in bits by

00111101 11001100 11001100 11001101
seeeeeee evvvvvvv vvvvvvvv vvvvvvvv
  • s: the sign bit means it's positive
  • e: exponent offset: 01111011 (123 in decimal) which means the exponent value is -4
  • v: stored value

so, 0.1 decimal is represented as (in binary):

1.1001100 11001100 11001101 x 2^-4

(The leading 1. is implicit)

then, you can add up all the bit values:

0.500000000000000000000000000000 x 0
0.250000000000000000000000000000 x 0
0.125000000000000000000000000000 x 0
0.062500000000000000000000000000 x 1  <--- start here
0.031250000000000000000000000000 x 1
0.015625000000000000000000000000 x 0
0.007812500000000000000000000000 x 0
0.003906250000000000000000000000 x 1
0.001953125000000000000000000000 x 1
0.000976562500000000000000000000 x 0 
0.000488281250000000000000000000 x 0
0.000244140625000000000000000000 x 1
0.000122070312500000000000000000 x 1
0.000061035156250000000000000000 x 0
0.000030517578125000000000000000 x 0
0.000015258789062500000000000000 x 1
0.000007629394531250000000000000 x 1
0.000003814697265625000000000000 x 0
0.000001907348632812500000000000 x 0
0.000000953674316406250000000000 x 1
0.000000476837158203125000000000 x 1
0.000000238418579101562500000000 x 0
0.000000119209289550781250000000 x 0
0.000000059604644775390625000000 x 1
0.000000029802322387695312500000 x 1
0.000000014901161193847656250000 x 0
0.000000007450580596923828125000 x 1  <<--- rounded up

added up equals:

0.100000001490116119384765625000

which is what you saw when you printed.

I've gone into more detail than you might have been asking about, but I wanted to illustrate exactly why using a float (or double) when dealing with finite amounts can end up giving you trouble.

If you multiply 4.2 * 100, you will get 419. Try it! The same principle applies.

For more intricate explanation with diagrams, see wikipedia: http://en.wikipedia.org/wiki/Single_precision_floating-point_format

Brenda.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .