1

With following code:

float f = 23.456;
printf("%f", f);

Output for different values of f are:

 Value       Output
---------    --------       
f = 23.456   23.455999 
f = 23.956   23.955999
f = 23.947   23.947001
f = 23.656   23.656000

Why is the value obtained unpredictable or there is a pattern?

Rafed Nole
  • 112
  • 1
  • 4
  • 16

3 Answers3

8

This falls into the category of things every programmer should know about floating point. The way that floating point works means that some numbers are not fully representable in floating point. The simplest way to explain this is to ask you to write down the value 1/3 as a decimal number. You start out quite happily, but eventually you end up running out of paper. The reason for this is that in base ten notation, the number 1/3 is infinitely long and so in a sensible encoding system which uses base ten notation to store the number, there is a limit to how long it can be.

Floating point does the same thing, but uses base 2. This means that numbers which seem really simple to us, e.g. 1/10 or 0.1, become infinitely recursive. This causes a roundoff error when you come to print the numbers, simply because the number you stored is not the number you gave to the compiler because it wasn't possible to store the number.

The canonical paper on this is http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html, which is a hefty read, but explains all of this and a lot more.

Stewart
  • 3,978
  • 17
  • 20
  • Floating point _often_ uses base 2. Had OP used a FP that was base 10, certainly not common, there would have been no question. IEEE 754-2008 specifies various decimal FP formats and suspect we'll see more of that in the future. – chux - Reinstate Monica Sep 06 '13 at 05:48
  • 2
    @chux - You're quite right that base 10 floats would solve this question, but that would just introduce the further question "float f = 1.f / 3.f; printf("%f", f);" get the answer wrong. There will always be numbers which cannot be precisely represented by a computer. – Stewart Sep 06 '13 at 05:52
4

It is because of IEEE 754 32-bit floating point format which is used by C to store floating point numbers. The Mantissa you have is converted in binary and stored in lower 23 bits of 4-byte space required by float variable. Sometimes it is completely convertible to exact binary, at other times it may not be exactly converted so a truncated form of the number is stored, which is when read from memory, evaluates to a slightly different value.

This behaviour is similar as in mathemetics you use value of 1/3 as 0.33 or 0.333 depending on your requirement of precision.

Try using:
f = 0.25; or,
f = -15.625; or, any decimal value exactly convertible to binary, you will get correct result.

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

With float or double you have a certain amount of bits to represent your number x in the computer. For float it's usually 32 bits and double has 64 bits.

The result of that? You can only store 2^32 different numbers in a float and 2^64 in a double. Since there is an infinite amount of "other" numbers, it means that these cannot be represented. But people still want to use these numbers (a compiler error about the unuseability of a number would be odd, wouldn't it?). Therefore, a number close to x is chosen. In most applications, this is a "close enough". But for the same reason: Never trust a float, i.e. never try to ask "is x = 5?".

stefan
  • 10,215
  • 4
  • 49
  • 90
  • i am missing something here: In the binary representation of floating point the no. stored (assume positive) will always be less than or equal to the actual number.so the round off that will be done will be smaller than the actual number.So why do we get larger values from printf? – Rafed Nole Sep 06 '13 at 05:48
  • @user2653718 Numbers won't always be rounded down. Afaik, the nearest representable number is chosen which often is slightly larger. – stefan Sep 06 '13 at 05:51
  • thx.the nearest representable 23 bit number may be obtained by changing last bit or 1-2 bits or some other way? – Rafed Nole Sep 06 '13 at 05:59
  • @user2653718: There's always one 23 number below the actual value and one above. These generally differ by 1 bit, but at some places the exponent changes and then the meaning of the last bit changes (by a factor of 2). Regardless, between the two the closest approximation is chosen. – MSalters Sep 06 '13 at 06:44