float variables in C [duplicate] - c

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.

Related

type of numbers that are not stored in a variable [duplicate]

This question already has answers here:
Is floating point math broken?
(31 answers)
Closed 4 years ago.
I'm a Little confused about some numbers in C-Code. I have the following piece of Code
int k;
float a = 0.04f;
for (k=0; k*a < 0.12; k++) {
* do something *
}
in this case, what is the type of "0.12" ? double ? float ? it has never been declared anywhere. Anyways, in my program the Loop above is excuted 4 times, even though 3*0.04=0.12 < 0.12 is not true. Once I Exchange 0.12 with 0.12F (because I am globally restricted to float precision in all of the program), the Loop is now executed 3 times. I do not understand why, and what is happening here. Are there any proper Guidelines on how to write such statements to not get unexpected issues?
Another related issue is the following: in the Definition of variables, say
float b = 1/180 * 3.14159265359;
what exactly "is" "1" in this case ? and "180" ? Integers ? Are they converted to float numbers ? Is it okay to write it like that ? Or should it be "1.0f/180.0f*3.14159265359f;"
Last part of the question,
if i have a fuction
void testfunction(float a)
which does some things.
if I call the fuction with testfunction(40.0/6.0), how is that Division handled ? It seems that its calculated with double precision and then converted to a float. Why ?
That was a Long question, I hope someone can help me understand it.
...numbers that are not stored in a variable
They are called "constants".
Any unsuffixed floating point constant has type double.
Quoting C11, chapter §6.4.4.2
An unsuffixed floating constant has type double. If suffixed by the letter f or F, it has
type float. If suffixed by the letter l or L, it has type long double.
For Integer constants, the type will depend on the value.
Quoting C11, chapter §6.4.4.1,
The type of an integer constant is the first of the corresponding list in which its value can
be represented. [..]
and for unsuffixed decimal number, the list is
int
long int
long long int
Regarding the mathematical operation accuracy of floating point numbers, see this post
"0.12" is a constant, and yes, without a trailing f or F, it will be interpreted as a double.
That number can not be expressed exactly as a binary fraction. When you compare k * a, the result is a float because both operands are floats. The result is slightly less than 0.12, but when you compare against a double, it gets padded out with zeros to the required size, which increases the discrepancy. When you use a float constant, the result is not padded (cast), and by good luck, comes out exactly equal to the binary representation of "0.12f". This would likely not be the case for a more complicated operation.
if we use a fractional number for eg, like 3.4 it's default type if double. You should explicitly specify it like 3.4f if you want it to consider as single precision (float).
if you call the following function
int fun()
{
float a= 1.2f;
double b = 1.2;
return (a==b);
}
this will always return zero (false).because before making comparison the float type is converted to double (lower type to higher type) , At this time sometimes it can't reproduce exact 1.2, a slight variations in value can be happen after 6th position from decimal point. You can check the difference by the following print statement
printf("double: %0.9f \n float: %0.9f\n",1.2,1.2f);
It results ike
double: 1.200000000
float: 1.200000481

Why did my float get truncated? [duplicate]

This question already has answers here:
C integer division and floor
(4 answers)
Closed 7 years ago.
#include <stdio.h>
int main(void)
{
float c =8/5;
printf("The Result: %f", c);
return 0;
}
The answer is 1.000000. Why isn't it 1.600000?
C is interpreting your 8/5 input as integers. With integers, C truncates it down to 1.
Change your code to 8.0/5.0. That way it knows you're working with real numbers, and it will store the result you're looking for.
The expression
8/5
is an all int expression. So, it evaluates to (int )1
The automatic conversion to float happens in the assignment.
If you convert to float before the divide, you will get the answer you seek:
(float )8/5
or just
8.0/5
When you don't specify what data types you use (for example, in your code you use the integer constants 8 and 5) C uses the smallest reasonable type. In your case, it assigned 8 and 5 the integer type, and because both operands to the division expression were integers, C produced an integer result. Integers don't have decimal points or fractional parts, so C truncates the result. This throws away the remainder of the division operation leaving you with 1 instead of 1.6.
Notice this happens even though you store the result in a float. This is because the expression is evaluated using integer types, then the result is stored as is.
There are at least two ways to fix this:
Cast the part of the expression to a double type or other type that can store fractional parts:
Here 8 is cast to the double type, so C will perform float division with the operands. Note that if you cast (8 / 5), integer division will be performed before the cast.
foo = (double) 8 / 5
Use a double as one of the operands:
foo = 8.0/5

Cant figure out the way compiler does the calculation

Given is a C code, in which i am trying to figure out how the calculation order would go, well i thought it should be 3/2 first and then *5 or the other way round. But it gives an unexpected output of
5.000000
#include <stdio.h>
int main(void) {
// your code goes here
float a = 3/2*5;
printf("%f", a);
return 0;
}
This is expected.
It calcuates 3/2 first (as integer), which is truncated down to 1. Then it multiplies by 5.
Try casting the numbers to (float) in your calculation - then you'll get the expected answer.
As suggested by damienfrancois, you can also get the compiler to treat them as floating point numbers as follows:
float a = 3.0/2.0*5;
In general, if you don't give any indication otherwise (such as the .0, or a cast), the compiler will treat numbers as an integer
The line
float a = 3/2*5;
computes a as the integer division of 3 by 2, which is 1, then multiplied by 5 and cast to float.
Replace it with
double a = 3.0/2.0*5;
or
float a = 3.0f/2.0f*5;
and you'll get 7.500000
It divides the integer 3 by integer 2, then multiplicates by integer 5, and then converts to a float.
Try float a = 3.f/2*5;
The multiplication and division operator have equal precedence in evaluation. Since both operators are left to right associative, integer division (3/2) is performed first resulting in 1 and then followed by multiplication with 5. Readup on operator associativity in C language
http://en.wikipedia.org/wiki/Operators_in_C_and_C%2B%2B#Operator_precedence

Different rounding between assignment and printf

I have a program with two variables of type int.
int num;
int other_num;
/* change the values of num and other_num with conditional increments */
printf ("result = %f\n", (float) num / other_num);
float r = (float) num / other_num;
printf ("result = %f\n", r);
The value written in the first printf is different from the value written by the second printf (by 0.000001, when printed with 6 decimal places).
Before the division, the values are:
num = 10201
other_num = 2282
I've printed the resulting numbers to 15 decimal places. Those numbers diverge in the 7th decimal place which explains the difference in the 6th one.
Here are the numbers with 15 decimal places:
4.470201577563540
4.470201492309570
I'm aware of floating point rounding issues, but I was expecting the calculated result to be the same when performed in the assignment and in the printf argument.
Why is this expectation incorrect?
Thanks.
Probably because FLT_EVAL_METHOD is something other than 0 on your system.
In the first case, the expression (float) num / other_num has nominal type float, but is possibly evaluated at higher precision (if you're on x86, probably long double). It's then converted to double for passing to printf.
In the second case, you assign the result to a variable of type float, which forces dropping of excess precision. The float is then promoted to double when passed to printf.
Of course without actual numbers, this is all just guesswork. If you want a more definitive answer, provide complete details on your problem.
The point is the actual position of the result of the expressions during the execution of the program. C values can live on the memory (which includes caches) or just on registers if the compiler decides that this kind of optimization is possible in the specific case.
In the first printf, the expression result is stored in a register, as the value is just used in the same C instruction, so the compiler thinks (correctly), that it would be useless to store it somewhere less volatile; as result, the value is stored as double or long double depending on the architecture.
In the second case, the compiler did not perform such optimization: the value is stored in a variable within the stack, which is memory, not register; the same value is therefore chopped at the 23th significant bit.
More examples are provided by streflop and its documentation.

Inconsistent results while printing float as integer [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
print the float value in integer in C language
I am trying out a rather simple code like this:
float a = 1.5;
printf("%d",a);
It prints out 0. However, for other values, like 1.4,1.21, etc, it is printing out a garbage value. Not only for 1.5, for 1.25, 1.5, 1.75, 1.3125 (in other words, decimal numbers which can be perfectly converted into binary form), it is printing 0. What is the reason behind this? I found a similar post here, and the first answer looks like an awesome answer, but I couldn't discern it. Can any body explain why is this happening? What has endian-ness got to do with t?
you're not casting the float, printf is just interpreting it as an integer which is why you're getting seemingly garbage values.
Edit:
Check this example C code, which shows how a double is stored in memory:
int main()
{
double a = 1.5;
unsigned char *p = &a;
int i;
for (i=0; i<sizeof(double); i++) {
printf("%.2x", *(p+i));
}
printf("\n");
return 0;
}
If you run that with 1.5 it prints
000000000000f83f
If you try it with 1.41 it prints
b81e85eb51b8f63f
So when printf interprets 1.5 as an int, it prints zero because the 4 LSBs are zeros and some other value when trying with 1.41.
That being said, it is an undefined behaviour and you should avoid it plus you won't always get the same result it depends on the machine and how the arguments are passed.
Note: the bytes are reversed because this is compiled on a little indian machine which means the least significant byte comes first.
You don't take care about argument promotions. Because printf is a variadic function, the arguments are promoted:
C11 (n1570), § 6.5.2.2 Function calls
arguments that have type float are promoted to double.
So printf tries to interpret your double variable as an integer type. It leads to an undefined behavior. Just add a cast:
double a = 1.5;
printf("%d", (int)a);
Mismatch of arguments in printf is undefined beahivour
either typecast a or use %f
use this way
printf("%d",(int)a);
or
printf("%f",a);
d stands for : decimal. so, nevertheless a is float/double/integer/char,.... when you use : "%d", C will print that number by decimal. So, if a is integer type (integer, long), no problem. If a is char : because char is a type of integer, so, C will print value of char in ASCII.
But, the problem appears, when a is float type (float/double), just because if a is float type, C will have special way to read this, but not by decimal way. So, you will have strange result.
Why has this strange result ?
I just give a short explanation : in computer, real number is presented by two part: exponent and a mantissa. If you say : this is a real number, C will know which is exponent, which is mantissa. But, because you say : hey, this is integer. no difference between exponent part and mantissa part -> strange result.
If you want understand exactly, how can know which integer will it print (and of course, you can guess that). You can visit this link : represent FLOAT number in memory in C
If you don't want to have this trange result, you can cast int to float, so, it will print the integer part of float number.
float a = 1.5;
printf("%d",(int)a);
Hope this help :)

Resources