-3

In printf("%d", (float) 9/ (float) 5); what will be the output?

Note: In printf function the format specifier is %d

It seems that output would be 0 just like the below code return answer 0.

float a = 9/5;
printf("%d",a);

[Edited] But not at all. The actual output is -1073741824 as a Garbage Value And that's the question. Why?

We can do the explicit typecasting to convert integer data type to float data type.

But why typecasting is not working in this printf("%d", (float) 9/ (float) 5); code?

I know this is a stupid question but I want to know this stupidity.

Sajjad Ali
  • 91
  • 2
  • 10
  • 1
    Your format specifier and value passed don’t match – Sami Kuhmonen Mar 27 '22 at 06:48
  • @SamiKuhmonen i know but below (2 lines) code returns zero but first one returns as a garbage why it is also not returning zero? – Sajjad Ali Mar 27 '22 at 06:51
  • Because 9/5 is not the same as `(float)9/(float)5` – Sami Kuhmonen Mar 27 '22 at 06:51
  • printf("%f", 9.0f / 5.0f); See https://www.cplusplus.com/reference/cstdio/printf/ for list of valid format and what each one is used for. Also see https://en.cppreference.com/w/cpp/language/floating_literal – John Mar 27 '22 at 07:00
  • @John i am sorry but can you tell me in the form of answer what you want to explain – Sajjad Ali Mar 27 '22 at 07:08
  • Do you have compiler warnings enabled? It should've warned you about this. – HolyBlackCat Mar 27 '22 at 07:11
  • _"It seems that output would be 0_" - why would `9/5` result in anything less than `1`? – Ted Lyngmo Mar 27 '22 at 07:28
  • @HolyBlackCat i didn't turned off so i think it would be turned on.. and no warnings displayed by compiler.. i am using gcc-mingw compiler in vs code – Sajjad Ali Mar 27 '22 at 07:32
  • @TedLyngmo because we are using %d format specifier instead of %f – Sajjad Ali Mar 27 '22 at 07:36
  • @SajjadAli It still doesn't make sense. The integer operation `9/5` results in `1`. Where do you get `0` from? Do `printf("%d\n", (int)a);` to verify. – Ted Lyngmo Mar 27 '22 at 07:37
  • *"i didn't turned off"* Most of them are probably off by default. How to turn them on depends on your compiler. – HolyBlackCat Mar 27 '22 at 07:42
  • 1
    There is no "correct" output for _undefined behaviour_. What makes you think that -1073741824 is somehow "correct". How can it be both _correct_ and _garbage_? different every time at https://www.onlinegdb.com/Q1Tlxf4Rl, and certainly different from your result. You cannot draw any conclusions from these results. – Clifford Mar 27 '22 at 07:43
  • @Clifford I know the result is differ as it is a garbage value and garbage value will be different on every memory in my memory there is -1073741824 and on another's memory there is different one – Sajjad Ali Mar 27 '22 at 07:52
  • Does this answer your question? [What is the behavior of integer division?](https://stackoverflow.com/questions/3602827/what-is-the-behavior-of-integer-division) – phuclv Mar 27 '22 at 08:25
  • Duplicate: [What happens when I use the wrong format specifier?](https://stackoverflow.com/q/16864552/995714) – phuclv Mar 27 '22 at 08:26
  • You missed my point - you stated that that value was somehow "correct". (you wrote: "_The correct output is -1073741824_") . If you think they should simply be the _same_ then you are _wrong_ both arithmetically and semantically, – Clifford Mar 27 '22 at 08:55

2 Answers2

1

printf() has no way to know what type you are passing in other than the "%d" format specifier you've given it. When it sees "%d" it will use va_arg() to extract an integer from the arguments it received. There is no integer there, so anything could happen. Floating point values are often passed in different registers than integers, so it's not like you're just interpreting a float as an int, you're actually loading an int from some unknown place.

John Zwinck
  • 239,568
  • 38
  • 324
  • 436
  • what is `va_arg()`can you explain or any article about it? – Sajjad Ali Mar 27 '22 at 06:54
  • @SajjadAli here is one reasonable reference: https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/va-arg-va-copy-va-end-va-start?view=msvc-170 - it is what `printf()` uses to get arguments from its `...` variadic parameter list. – John Zwinck Mar 27 '22 at 07:07
  • @SajjadAli Here's a [toy example](https://godbolt.org/z/5osK3j9PY) if you want to experiment – Ted Lyngmo Mar 27 '22 at 08:15
1

The value of (float)9 / (float)5 (or more simply 9.0f / 5.0f) is 1.8f. Whereas the value of 9/5 is 1, and when assigned to a float implicitly cast to 1.0f (equivalent to (float)(9/5)).

In both cases interpreting either value using the %d format specifier has undefined behaviour but the result differing is hardly surprising since the input differs. That said even if the values were the same, that too should not be surprising - that is the thing with undefined behaviour - all bets are off.

Consider:

float a = 9.0f / 5.0f ;
printf( "%d\n", *(int*)(&a) ) ;

float b = 9 / 5 ;
printf( "%d\n", *(int*)(&b) ) ;

Both display the bit patterns of a and b respectively interpreted as an int. The results are deterministic and reflect the values 1.8f and 1.0f passed. The output values in hexadecimal:

a = 3FE66666
b = 3F800000

correspond to 1.8 and 1.0 respectively at https://www.h-schmidt.net/FloatConverter/IEEE754.html

Experimenting with variations of your "undefined behaviour" code, there is no consistency - the results are non-deterministic and have no meaning or correspondence to the values passed.

Clifford
  • 88,407
  • 13
  • 85
  • 165