-1

I was trying to see how different languages handle floating point numbers. I know that there are some inherent issues in floating point representation, which is why if you do 0.3 + 0.6 in Python, you get 0.899999 and not 0.9

However, these snippets of code simply left me astounded:

double x = 0.1,
    sum = 0;

for(int i=0; i<10; ++i) 
    sum += x;

printf("%.9lf\n",sum);
assert(sum == 1.0);

The above snippet works fine. It prints 1.0. However, the following snippet gives a runtime error due the assertion failing:

double x = 0.1,
    sum = 0;

for(int i=0; i<10; ++i) 
    sum += x;

assert(sum == 1.0);
printf("%.9lf\n",sum);

The only change in the two snippets above is the order of the assert and printf statements. This leads me to think that printf is somehow modifying its arguments and rounding them off somehow.

Can someone please throw some light on this?

Akshay Damle
  • 1,220
  • 3
  • 18
  • 31
  • Try 16 digits instead of 9. – Jonathan Leffler Sep 24 '15 at 20:17
  • 8
    Please never *ever* ask for help on an error you are getting without bothering to state what error you are getting. This is insanity. – Jonathan Wood Sep 24 '15 at 20:17
  • This appears to be another instance of not understanding how floating point numbers work. Throw on top of that a misunderstanding of printf and you have a mess. – duffymo Sep 24 '15 at 20:18
  • 2
    [because](http://codeblog.jonskeet.uk/2009/11/02/omg-ponies-aka-humanity-epic-fail/) – Dmitry Ledentsov Sep 24 '15 at 20:20
  • `printf` is a C function. C functions receive their parameters by value, not by reference, so they can't modify them (except for arrays, which are converted to pointers when passed to functions). – Barmar Sep 24 '15 at 20:23
  • @duffymo I do understand how floating point numbers work. I simply did not know that the registers used to store them were bigger in order to have higher precision, as Joseph mentioned. Your comment does not add anything of value to the thread. – Akshay Damle Sep 24 '15 at 22:40
  • @duffymo Seriously? On what grounds are you saying that? It's a perfectly valid question according to me. Your comments appear to be another instance of not knowing the answer. Throw on top of that ignorance and blatant rudeness, and you have a mess. – Akshay Damle Sep 25 '15 at 20:54
  • Also, Jonathan, I'm not sure what more information you need to solve my problem. The runtime error in the second snippet is obviously because the assert fails. I simply want to know why it fails in the second snippet and not in the first. Please tell me how that is insanity so that I can try to be sane next time I post a question. – Akshay Damle Sep 25 '15 at 21:01

2 Answers2

7

Some processors, such as x86, have floating point registers that are higher precision than the data type (80 bit, compared to 64 bit for a double). Calling printf() causes these registers to be stored on the stack, where there is only 64 bits allocated for the variable. This causes the difference you are observing.

For more information see What every computer scientist should know about floating-point arithmetic.

Joseph Stine
  • 1,022
  • 1
  • 12
  • 23
  • How does *"calling print() causes these registers to be stored on the stack"?* They are passed on the stack to `printf()`, but how does that alter the original variable `sum`? – Jonathan Wood Sep 24 '15 at 23:16
  • Without a call to printf() (or any other function) it is possible that the variables are stored in registers. If thre is a function call, the variables will have to be saved on the stack, because the compiler cannot guarantee that the function being called will not use those registers for something else. – Joseph Stine Sep 25 '15 at 00:13
  • I see what you're saying. Interesting if that is what is causing this. – Jonathan Wood Sep 25 '15 at 00:35
0

printf() does not modify its parameters.

I can't imagine asking help for an error and not stating what error you are getting. Do you mean it asserts. Are you sure that both don't assert, but you only see the one that asserts before the printf() for some reason?

Neil Kirk
  • 21,327
  • 9
  • 53
  • 91
Jonathan Wood
  • 65,341
  • 71
  • 269
  • 466
  • I'm not sure I understand your question. The first code snippet does not give me a runtime error but the second one does. I don't understand why this is so. – Akshay Damle Sep 24 '15 at 22:47