1

I have read that floating numbers are stored as per IEEE 754 representation and sometimes approximate value is displayed if its not possible to represent the number.

I have written the following code in which i am extracting fractional part then multiplying it by 10 nine times inside the loop. At the end of the loop the value is 142000000.000000 (variable g). I multiplied it again with 10 outside the loop and got the result as 1419999999.999999.

I stored the value which was calculated inside for loop explicitly in another variable(k) and multiplied it with 10 and got the result as 1420000000.000000

Can you please tell me why the difference how it is able to store the value correctly in the second instance (In variable k).

#include<stdio.h>
#include<math.h>
int main()
{
    double f=3.142,g,i;
    int j;
    g=modf(f,&i);

    printf("Inside loop");
    for(j=1;j<=9;j++)
    {
        g = g * 10.0;
        printf("\n%lf",g);
    }
    printf("\nLoop ends");

    g = g * 10.0;
    printf("\nThe value of g is %lf",g);

    double k = 142000000.000000;
    k = k * 10.0;
    printf("\nThe value of k is %lf",k);
}

Output

Inside loop

1.420000

14.200000

142.000000

1420.000000

14200.000000

142000.000000

1420000.000000

14200000.000000

142000000.000000

Loop ends

The value of g is 1419999999.999999

The value of k is 1420000000.000000

Kailash
  • 642
  • 2
  • 9
  • 15
  • "I have read that floating numbers are stored as per IEEE 754 representation" - that is wrong. The standard does not enforce a specific encoding or behaviour for border-cases. – too honest for this site Mar 13 '17 at 18:06
  • 2
    Please remember that a 64-bit variable can still only store 2**64 discrete values. That is part of the reason for the approximation, since `double` covers a far greater *range* than `int64_t` does. – Weather Vane Mar 13 '17 at 18:10
  • 1
    [Using a union to inspect the actual memory value of the double](https://stackoverflow.com/questions/397692/how-do-i-display-the-binary-representation-of-a-float-or-double#397700), sheds light on what's going on. Multiplying 1.42 by 10 a bunch of times does not result in the same underlying number as the constant 142000000.000000 even if they happen to display the same. – Schwern Mar 13 '17 at 18:13
  • Multiplying by 10 repeatedly only magnifies the error in representation that already existed in `3.142`. – Weather Vane Mar 13 '17 at 18:14
  • @KeineLust "%lf is for long double, ..." `"%lf"` and ``"%f"`` are both fine for printing`double`. `"%Lf"` (Uppercase L) is for `long double` – chux - Reinstate Monica Mar 13 '17 at 19:01
  • 1
    To see the exact value of `g`, use `printf("%a\n",g);` To see it precisely in decimal, try `printf("%.17e\n",g);` – chux - Reinstate Monica Mar 13 '17 at 19:04

1 Answers1

2

The initial value of f is 3.142. This value can't be represented exactly, so any operations on this value will also result in an inexact value. That's why you eventually end up printing an inexact value.

In contrast, the initial value of k is 142000000.000000 which can be represented exactly as a double. Multiplying this value by 10 still gives a value that can be represented exactly.

dbush
  • 205,898
  • 23
  • 218
  • 273
  • Ok as per that at the end of for loop the value of g is not exactly 142000000.000000 but an approximate value of some other stored value. so any multiplication on that may yield inexact answer (not my expected answer). Whereas in the second case variable k the stored value is exactly 142000000.000000 so i get the desired answer after multiplication. Is that what you are saying. Correct me if i am wrong. – Kailash Mar 13 '17 at 18:16
  • @Kailash That is correct. – dbush Mar 13 '17 at 18:22