7
#include<stdio.h>
void main(){
   printf("%f\n",5/9);  // prints 0.000000
   printf("%f\n",9.0/5.0); // prints 1.800000
   printf("%f\n",5/9);  // prints 1.799999
}

The 5th line value should print 0.000000 like in 3rd line

I have tried in local machine and online compiler the results were same

jpa
  • 10,351
  • 1
  • 28
  • 45
Jim Stone
  • 71
  • 3
  • 5
    While indeed this could be found out by compiler warnings, +1 for new contributor for providing a reproducible example and good description. – jpa Aug 03 '23 at 06:14
  • 1
    Please read [this](https://stackoverflow.com/questions/57842756/why-should-i-always-enable-compiler-warnings). – n. m. could be an AI Aug 03 '23 at 06:51
  • 2
    Unless you are programming in a *freestanding environment* (without the benefit of any OS), the allowable declarations for `main` for are `int main (void)` and `int main (int argc, char *argv[])` (which you will see written with the equivalent `char **argv`). *See*: [C11 Standard - §5.1.2.2.1 Program startup(p1)](http://port70.net/~nsz/c/c11/n1570.html#5.1.2.2.1p1). *See also*: [What should main() return in C and C++?](http://stackoverflow.com/questions/204476/) In a freestanding environment, the function name and type called at startup are implementation-defined. – David C. Rankin Aug 03 '23 at 06:59
  • For expanded discussion of why you see what you see, See: [Undefined, unspecified and implementation-defined behavior](https://stackoverflow.com/q/2397984/3422102) and [What is indeterminate behavior in C++ ? How is it different from undefined behavior?](https://stackoverflow.com/q/11240484/3422102) and [Undefined behavior](https://en.cppreference.com/w/c/language/behavior) – David C. Rankin Aug 03 '23 at 07:04
  • 3
    I especially like that my "floating point math is broken" reflex is wrong here. ;-) – Yunnosch Aug 03 '23 at 07:55

2 Answers2

12

printf("%f\n",5/9); // prints 1.799999

You are passing an integer value, while specifying double-precision floating point format. In practice this causes printf() to read uninitialized memory, which can contain pretty much anything.

In this case it contains the left-overs of the previously printed 1.8 and the integer 0 only replaces the lower bits of it, causing a small change in value.

Turn on your compiler warnings (e.g. -Wall in GCC and clang), and you should get a warning like warning: format '%f' expects argument of type 'double', but argument 2 has type 'int'.

jpa
  • 10,351
  • 1
  • 28
  • 45
  • 5
    Be careful with attempting to explain undefined behaviour. You might give the wrong impression, that the behaviour your describe can be relied upon "in this case". If the "this case" is misunderstood, people might misunderstand altogether. – Yunnosch Aug 03 '23 at 07:52
  • 3
    @Yunnosch I agree that it makes no sense to rely on this behavior. But when debugging, it is very useful to understand what kind of effects undefined behavior usually has. The strict interpretation of *"something weird is happening, this can be caused by undefined behavior anywhere in the program"* is not useful for finding the mistake. – jpa Aug 03 '23 at 08:25
  • 1
    I go along with that. I also like to look for "possible explanation in this possibly unique case" for finding fixes. It is just that on this question, I would expect each answer to at least mention "undefined behaviour" or "nasal demons" (which is guaranteed in my opinion to cause people to research....). As you can see in my comment on the other answer, I also do not like to ONLY say "UB. Done.". Though that also is something I sometimes do, but usually with something going along your "try to explain" line. .... hope I make sense... – Yunnosch Aug 03 '23 at 09:13
9

The division 5 / 9 is an integer operation, with an integer result (of type int).

The format specifier %f expects a double value.

Mismatching format specifier and argument type leads to undefined behavior.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • True. But for some readers (not necessarily "most", but "many") "undefined behaviour" is not a complete explanation, though, assuming a research on that technical term, it implicitly is. – Yunnosch Aug 03 '23 at 07:54
  • @Yunnosch I tried the code. The 2nd and the 3rd `printf` give me the same value : `1.800000`. The 3rd is still wrong, but it is different than the one in the question. So to anyone who might be tempted to : one should not try to explain *undefined behaviour*. – nquincampoix Aug 27 '23 at 14:22