Why the division of two integers return 0.00? [duplicate] - c

This question already has answers here:
printf("%f", aa) when aa is of type int [duplicate]
(2 answers)
Closed 7 years ago.
Every time I run this program I get different and weird results. Why is that?
#include <stdio.h>
int main(void) {
int a = 5, b = 2;
printf("%.2f", a/b);
return 0;
}
Live Demo

printf("%.2f", a/b);
The output of the division is again of type int and not float.
You are using wrong format specifier which will lead to undefined behavior.
You need to have variables of type float to perform the operation you are doing.
The right format specifier to print out int is %d

In your code, a and b are of type int, so the division is essecntially an integer division, the result being an int.
You cannot use a wrong format specifier anytime. %f requires the corresponding argument to be of type double. You need to use %d for int type.
FWIW, using wrong format specifier invokes undefined behaviour.
From C11 standard, chapter §7.21.6.1, fprintf()
If any argument is not the correct type for the corresponding conversion specification, the behavior is undefined.
If you want a floating point division, you need to do so explicitly by either
promoting one of the variable before the division to enforce floating point division, result of which will be of floating point type.
printf("%.2f", (float)a/b);
use float type for a and b.

You need to change the type as float or double.
Something like this:
printf("%.2f", (float)a/b);
IDEONE DEMO
%f format specifier is for float. Using the wrong format specifier will lead you to undefined behavior. The division of int by an int will give you an int.

Use this instead of your printf()
printf("%.2lf",(double)a/b);

Related

Expected value not obtained: why? [duplicate]

This question already has answers here:
printf specify integer format string for float
(7 answers)
Closed 5 years ago.
I wrote this very simple and short code, but it doesn't work: when I compile and execute the returned value from the function calculateCharges() is 0 when I'm expecting 2.
Can anybody explain why, please?
#include <stdio.h>
#include <stdlib.h>
float calculateCharges(float timeIn);
int main()
{
printf("%d", calculateCharges(3.0));
return 0;
}
float calculateCharges(float timeIn)
{
float Total;
if(timeIn <= 3.0)
Total = 2.0;
return Total;
}
There are at least three problems here, two of which should be easily noticeable if you enable compiler warnings (-Wall command-line option), and which lead to undefined behavior.
One is wrong format specifier in your printf statement. You're printing a floating point value wirh %d, the format specifier for signed integer. The correct specifier is %f.
The other is using uninitialized value. The variable Total is potentially uninitialized if the if statement in your function isn't gone through, and the behavior of such usage is undefined.
From my point of view, it's likely the wrong format specifier that caused the wrong output. But it's also recommended that you fix the second problem described above.
The third problem has to do with floating point precision. Casting values between float and double may not be a safe round-trip operation.
Your 3.0 double constant is cast to float when passed to calculateCharges(). That value is then cast up to a double in the timeIn <= 3.0 comparison (to match the type of 3.0).
It's probably okay with a value like 3.0 but it's not safe in the general case. See, for example, this piece of code which exhibits the problem.
#include <stdio.h>
#define EPI 2.71828182846314159265359
void checkDouble(double x) {
printf("double %s\n", (x == EPI) ? "okay" : "bad");
}
void checkFloat(float x) {
printf("float %s\n", (x == EPI) ? "okay" : "bad");
}
int main(void) {
checkFloat(EPI);
checkDouble(EPI);
return 0;
}
You can see from the output that treating it as double always is okay but not so when you cast to float and lose precision:
float bad
double okay
Of course, the problem goes away if you ensure you always use and check against the correct constant types, such as by using 3.0F.
%d will print integers.
Total is a float, so it will not work.
You must use the proper specifier for a float.
(You should research that yourself, rather than have us give you the answer)

Adding an Integer to a float not working as expected

I know the following will not print 2.9 or 3. I can correct it but really want to understand what is internally happening so it is printing:
858993459
How does this number come ?
I am running this under windows 32 bit
int main()
{
double f = 1.9;
int t = 1;
printf("%d\n", t+f);
return 0;
}
Update
Simply believing that this would be "undefined behavior" was not possible for me, so I thought of investigating it further. I found this answer exactly what I wanted to understand.
As others have already mentioned, this is undefined behaviour. But by taking some assumptions about the machine architecture, one can answer why it is printing these numbers:
Using IEEE 754 64-bit format to represent doubles values, the value of 2.9 is the a stored as 0x4007333333333333.
In a Little-Endian machine, the %d specifier will read the lower 4 bytes of that value, which are 0x33333333, which equals 858.993.459
you're using wrong format specifier. use %f instead.
As per the implicit type promotion rule, while doing t+f, t will be promoted to double. You're trying to print a double value using %d, which is supposed to expect an int.
Note: While using wrong format specifier, the behaviour is undefined.
Related reading: c99 standard, chapter 7.19.6.1, paragraph 9, (emphasis mine)
If a conversion specification is invalid, the behavior is undefined. If any argument is
not the correct type for the corresponding conversion specification, the behavior is
undefined.
What happened is you try print a double using %d, so printf interpret this how an integer, but for you understand why this printed value, you have to understand how a double is stored by C language, C uses the IEEE 754 standard:
So %d interpret this as integer, and when you add an int and an double C keep this as double to not lose any part, and the result is a double, and %d interpret this sum as a integer, and like the format is different you see garbage.
you should use %f instead.
You are trying to add integer and double so according to the thumb rule(type promotion rule) i.e. while this addition happens the integer will be promoted to double and the summation will happen and you are trying to print double value using %d format specifier which will lead to undefined behavior.
Use %f instead
PS: Using a wrong format specifer to print the value will lead to undefined behavior that is what you are seeing here.
%d will transfer double to int
double f = 1.9;
printf("%d\n", f);
Outputs:
1717986918
Computers store ints and doubles in different ways, you can see it here:
http://en.wikipedia.org/wiki/Double-precision_floating-point_format

Problems with scanf and doubles [duplicate]

This question already has answers here:
Why does scanf() need "%lf" for doubles, when printf() is okay with just "%f"?
(5 answers)
Closed 8 years ago.
im having trouble understanding why this occurs:
with the following code;
#include <stdio.h>
int main()
{
double x=123;
printf("x is %f. Enter a new value for x.\n", x);
scanf("%f", &x);
printf("x is %f\n", x);
return 0;
}
when you enter 45678 as the new value for x, 'x is 123.000017' is printed.
I know that this is fixed when you use %lf when scanning, but why does this happen when using %f?
I know that this is fixed when you use %lf when scanning, but why does this happen when using %f?
The difference between printf and scanf function arguments is that you pass values to printf, but to scanf you pass pointers (i.e. addresses of values). According to C rules, when a function takes a variable number of arguments, all parameters undergo default promotions.
One of the promotions is that floats get converted to double, in the same way that shorts get converted to int. That is why you can use %f or %lf with printf: both types of values are converted by the compiler to double, so accessing them is safe.
However, there is no such rule for pointers (and for a good reason: trying to write a double into a space of float would be undefined behavior). That is why you must differentiate between %f and %lf when passing parameters to the scanf family of functions.
scanf("%f", &x);
should be
scanf("%lf", &x);
There is a false symmetry for floating points conversion specifiers between printf and scanf.
Also note that lf conversion specifier is equivalent to f conversion specifier in printf (since c99, it was undefined before).
I know that this is fixed when you use %lf when scanning, but why does this happen when using %f?
f conversion specifier in scanf requires an argument of type pointer to float. By passing an argument of type pointer to double you invoke undefined behavior.

float variables in C [duplicate]

This question already has answers here:
Using %f to print an integer variable
(6 answers)
Closed 3 years ago.
May be this is a simple question but I am not sure about how float variables are stored in memory and why it is behaving in this way, can someone please explain about the following behavior.
#include<stdio.h>
int main ()
{
int a = 9/5;
printf("%f\n", a);
return 0;
}
Output:
0.000000
I have looked at some information on how float variables are stored in memory, it has stuff about mantissa, exponent and sign. But I am not getting how to relate that here.
int a = 9/5;
performs integer division and ignores the remainder, so a is set to 1. Attempting to print that using %f gives undefined behavior, but by chance you got 0.000000 out of it.
Do
double a = 9./5.;
instead, or print with %d if integer division was the desired behavior. (float would also work, but a will be promoted to double when passed to printf, so there's no reason not to use double.)
It is an Undefined Behaviour.
You are using float format specifier (%f) to print an int (a). You should use %d to see correct output.
It is an undefined behaviour in C. Use %d format specifier instead of %f.
Does printf() depend on order of format specifiers? gives you detailed answer.
Here's a brief analysis of your code:
int a = 9/5; // 9/5 = 1.8, but since you are doing integer division and storing the value in an integer it will store 1.
printf("%f\n", a);//Using incorrect format specifiers with respect to datatypes, will cause undefined behavior
printf("%d\n",a);//This should print 1. And correct.
Or if you want the float:
instead of int use float :
float a=9.0f/5;//This will store 1.800000f
//float a=9/5 will store 1.000000 not, 1.8 because of integer divison
printf("%f\n",a); //This will print 1.800000
Also do read this: http://en.wikipedia.org/wiki/IEEE_754-2008 on how floating points work.
Clarification about integer division:
C99:
6.5.5 Multiplicative operators
6 When integers are divided, the result of the / operator is the algebraic quotient with any fractional part discarded.88) If the quotient a/b is representable, the expression (a/b)*b + a%b shall equal a
88) This is often called ‘‘truncation toward zero’’.
Just assuming that your division should result in a fraction in normal math won't magically make it a float.
int a = 9/5;
You need to use
float a = 9.0/5;
First you need the right data type i.e. float (or better yet double for higher precision) to store a float.
Secondly, if you are dividing two integers i.e. 9 and 5, it will simply follow integer division i.e. only store the integer part of division and discard the rest. To avoid that i have added .0 after 9. This would force compiler to implicitly covert into float and do the division.
Regarding your mentioning of why it is printing 0, it is already mentioned that trying %f on integer is undefined behavior. Technically, a float is 4 bytes containing 3 byte number and 1 byte exponent and these are combined to generate the resultant value.

default argument promotion

main(){
printf("%d %d",1234.5);
}
output: 0 1083394560
This is the case of default argument promotion where float variable is treated as double and then first %d displays 0 and other one displays the value of rest 4 bytes i.e. 1083394560.
My question is if %d reads first 4 bytes then how does this program
main()
{
printf("%f",1234.5);
}
gives the right output. Because float is also of 4 bytes, it should also behave like %d.
Huh? %f can "know" that a float passed as a vararg argument has been promoted to something bigger (double) and act accordingly, of course. The code for %d does not know that it should expect a promoted floating point value; it expects a (suitably promoted) int.
The %f format string takes a double value in the argument list, and prints it out. Since un-suffixed floating point literals are doubles in C, and that doubles are not promoted or otherwise changed by default promotion rules, there is no magic at all happening with your second example.
Your first example is undefined behavior, anything could happen.
C99 §7.19.6.1 The fprintf function
If there are insufficient arguments for the format, the behavior is
undefined.
[...]
If any argument is
not the correct type for the corresponding conversion specification, the behavior is
undefined.
You answer your question by yourself:
This is the case of default argument promotion where float variable is treated as double
Of course, %f knows about this default argument promotion and only deals with doubles, not with floats.

Resources