If I have float a = 12.767; and I printf("%d",a); Why it does not printf 13 as I am printing aa float as an int?
Asked
Active
Viewed 43 times
0
-
Basically because `printf` isn't smart enough to do that. – Steve Summit Nov 29 '21 at 13:47
-
You need to do `printf("%d",(int)a);`. But this truncates, it does not round. – Lundin Nov 29 '21 at 13:48
-
When you pass numbers to `printf`, with one or two exceptions, no automatic conversions happen. Definitely no conversions happen due to mismatches between the type you pass, and the type expected by the `%`-specifier you use. These days, integers and floating-point values can get passed using completely different mechanisms. So when you pass a `float`, but tell printf (via `%d`) to expect an `int`, what `printf` actually gets when it goes to fetch an `int` may be basically a random value, unrelated to the `float` value you passed. – Steve Summit Nov 29 '21 at 13:51
-
Or you could `printf("%.0f", a);` – Fred Larson Nov 29 '21 at 13:52
-
So basically if printf ("%d", a) expects an int and a is a float, it will printf a random number because that is not an int. So this is like apples with apples and banas with bananas. I mean if I want to printf a float the value must be a float and if I want to printf an int, the value must be an int. Otherwise it will take a random value. Is correct what I have said? – rayo7 Nov 29 '21 at 14:08
-
@rayo7 That is basically correct. You can pass `float` when printf expects `double` (that is, for `%f` and `%g`). You can pass `char` or `short int` when printf expects `int` (that is, for `%d` and `%c`). You can pass `unsigned char` or `unsigned short int` when printf expects `unsigned int` (that is, for `%o` and `%x`). Otherwise, the types should match exactly. (The actual rules are a little more complicated than this, especially when it comes to the nuances of `unsigned`. In particular, what I said about `char` and `%d` was slightly wrong, and someone's about to correct me.) – Steve Summit Nov 29 '21 at 14:12
-
Question 1- Why if int a= 13 and I printf ("%f", a) it shows always 0.0000 (it does not matter the value of the int it also shows 0.000 if a=27) and it does not show a random number as in b=13.78 printf ("%d, b) ithat shows a random number? – rayo7 Nov 29 '21 at 14:17
-
@rayo7: Undefined behavior is *undefined* -- there's no telling what will happen. – Fred Larson Nov 29 '21 at 14:18
-
Question 2- Why if I define double a = 56.76; and I printf("%f", a) it does not show a random value, (it shoud be %lf because it is a double type not a float type. – rayo7 Nov 29 '21 at 14:23
-
@rayo7: Both `%f` and `%lf` [expect a `double` argument](https://en.cppreference.com/w/c/io/fprintf). A `float` argument is converted to `double` when passed to `printf`. – Fred Larson Nov 29 '21 at 14:24
-
But why if float a = 32.89; and I printf("%lf", a); the output is 32.889999 and if double a = 32.89; and I printf ("%f", a) ; the output here is 32.890000. Why the outputs are differents if printf transform float to double if it is %lf and double to float if it is %f? – rayo7 Nov 29 '21 at 14:34
-
Re "*When you pass numbers to printf, with one or two exceptions, no automatic conversions happen.*", Those are: Standard integer promotions (`char`, `signed char`, `unsigned char`, `signed short`, `unsigned short` become `signed int` or `unsigned int`) and, `float` is converted to `double`. – ikegami Nov 29 '21 at 14:39
-
@ikegami so why if I pass a float 32.8900 to printf and i use %lf as well as you said it is an exception and the float is converted to double so 32.8900 was a float and now is a double, but the value now is 32.89999. Why the value has changed? I don't understand it – rayo7 Nov 29 '21 at 14:50
-
Re "*so why if I pass a float 32.8900 to printf and i use %lf as well as you said it is an exception*", That's not true. C doesn't even have exceptions, for starters. And it's not an error or warning either. In fact, `%lf` was only introduced to `*printf` in C99, and it means the same as `%f`. – ikegami Nov 29 '21 at 14:56
-
Re "*Why the value has changed?*", The value didn't change. Your had the `float` 32.8899993896484375, and that didn't change when it was upgraded to a `double` when passed to `printf`. – ikegami Nov 29 '21 at 15:01
-
1Keep in mind that 89/100 is a periodic number in binary just like 1/3 in decimal. It can't be represented exactly by a floating pointer number (`float` or `double`). Truncating the periodic number at different points (`float` vs `double`) results in different numbers. With a IEEE double-precision number (a `double` on a x68/x64), is the closest number to 32.89 to 32.8900000000000005684341886080801486968994140625. With as single-precision (`float` on a x68/x64), 32.8899993896484375. – ikegami Nov 29 '21 at 15:03
-
[Demo](https://godbolt.org/z/944YMhqcv) – ikegami Nov 29 '21 at 15:06
-
@rayo7 Curious, Who or what text suggest `float` type and not `double a = 12.767;`? – chux - Reinstate Monica Nov 29 '21 at 15:15
-
@ikegami Re: Those are: Standard integer promotions (char, signed char, unsigned char, signed short, unsigned short become signed int or unsigned int) and, float is converted to double. What do you mean "those are". I thought you were referring to the exceptions as the other user said "with one or two expceptions" and you awnsered, those are.. What were you referring then? – rayo7 Nov 29 '21 at 15:16
-
Those are the implicit type conversion performed on arguments provided to `*printf`. So yes, those are the exceptions to "no automatic conversions happen" Steve Summit mentioned. You provide a `char`, it will get promoted to an `signed int` or `unsigned int`. You provide a `float`, it will get promoted to a `double`. – ikegami Nov 29 '21 at 15:18
-
@ikegami so you said that float is an exception and is converted to double in printf and later I said "so why if I pass a float 32.8900 to printf and i use %lf as well as you said it is an exception and the float is converted to double " and you awnsered "That's not true. C doesn't even have exceptions, for starters.". I don't understand then, you said that a float is an exception and in printf if there is %lf it is converted to double... – rayo7 Nov 29 '21 at 15:28
-
Sorry, I thought you meant it threw an exception. Re "*so why if I pass a float 32.8900 to printf and i use %lf as well as you said it is an exception*", Cause it's one of the cases where C does perform an automatic conversion. To a `double`, to be specific. – ikegami Nov 29 '21 at 15:29
-
@ikegami and what is the difference between trowing an exception and being an expeption? I don't know what does it mean to throw an exception – rayo7 Nov 29 '21 at 15:32
-
It doesn't exist in C, so not relevant here. – ikegami Nov 29 '21 at 15:34
-
@ikegami so basically my conclusion is that double type and float type have different precisions methods so for this reason reading a float number and a double number it does not matter that the number is the same because the output will be different due to the different precisions of double and float.Am I wrong? – rayo7 Nov 29 '21 at 15:57