How does printf work? Why is the output different? [duplicate] - c

This question already has answers here:
What happens to a float variable when %d is used in a printf?
(4 answers)
Closed 6 years ago.
Consider these two programs:
#include <stdio.h>
int main()
{
int z = 6.4;
printf("%d %d", z, 6.4);
return 0;
}
Output is 6 -1717986918.
#include <stdio.h>
int main()
{
int z = 6.4;
printf("%d %d", 6.4, z);
return 0;
}
Output is -1717986918 1075419545.
Why does the output vary like that? When z was first then the output printed correct z value which was 6 as z is an integer, but when I reversed the arguments, the output is a different value. Why does it behave like that?

You store 6.4 in an integer which will result in z being 6. The 6 gets passed to printf which is interpreting the passed value as an decimal, thus the correct output was displayed.
But if you pass a floating point number directly to printf, and specifying the format %d, it will also interpret it as an decimal which will result in the decimal interpretations of that float.
This interpretation happens on a bit level. Float is internally stored in a rather complex format. But not like an integer.
Now those bits get interpreter as an integer, and obviously the result is unreadable for humans. But the program could actually interpreted that integer as an float and reverse this action.
This site will demonstrate how floats are stored on the bit level.
And on this website you can convert the bits from the previous site to an signed integer which should output the negative number you specified in the question.

Related

C pow() function printing gigantic numbers? [duplicate]

This question already has answers here:
c++ pow(2,1000) is normaly to big for double, but it's working. why?
(3 answers)
Closed 1 year ago.
sorry if this is a silly question, I am relatively new to C programming. Thus I have probably misunderstood something fundamental about variables/overflows.
I made this simple program and I can't explain the result
#include <stdio.h>
#include <math.h>
int main() {
double number = pow(2, 1000);
printf("%f\n", number);
}
The result of that (compiled with gcc) is a humongous number that should never fit in a variable of type double: 10715086071862673209484250490600018105614048117055336074437503883703510511249361224931983788156958581275946729175531468251871452856923140435984577574698574803934567774824230985421074605062371141877954182153046474983581941267398767559165543946077062914571196477686542167660429831652624386837205668069376.000000
Usually when I try to assign a constant that is too large for it's type the compiler gives me an error.
So my question is: What is this number? Why am I not getting any errors? Is the variable number actually storing this value? Plainly, what's happening?
Doubles are not stored like integers. This page explains how double are representated in memory
Doubles contain 1 byte of sign, 11 bits for the exponent and 53 bits for the sigificand precision. Thus you can store numbers up to 1.7*10^308. Thus, your number cand be represented in a double (although with a limited precision). When printing it with %f, you just get its numerical value (approximated).
In C, double type can fit more than 300 decimal digits! A double is stored in 8 bytes, holding a number in the range 2.3E-308 to 1.7E+308 (15 decimal places accuracy).
Reference: https://www.tutorialspoint.com/cprogramming/c_data_types.htm

I made a simple C program to receive a float as input from user and display it in screen. But the value changes by a small amount while printing [duplicate]

This question already has answers here:
Why do I see a double variable initialized to some value like 21.4 as 21.399999618530273?
(14 answers)
Closed 1 year ago.
I made a simple C program to get a float as input from the user using scanf() function and dispay it using printf() function. But when the input number is quite large, the output deviates slightly. Why might that happen?
For example: if I give input as 2345, out put will be as expected. But if I give the output as 1234567898, the output will be unexpected.
#include <stdio.h>
int main()
{
float number;
scanf("%f", &number);
printf("The number %f", number);
return 0;
}
Single precision floating point (float) is good for approximately 6 significant decimal digits. double allows 15 significant figures. 1234567898.0 has 10 significant figures. Only the most significant first 6 digits can be relied on.

Float value input error [duplicate]

This question already has answers here:
Is floating point math broken?
(31 answers)
Closed 7 years ago.
With working with floating point values I don't know why my C compiler or the System is behaving unexpectedly. Not making it so confusing. Here is a simple program to take float value input and print the same.
#include <stdio.h>
int main()
{
float num;
printf("Enter float value ");
scanf("%f", &num);
printf("Value = %f", num);
return 0;
}
On multiple run of the same code giving me different and weird outputs. Here are some sample runs.
Sample Run #1 Correct Output
Enter float value 12.0312
Value = 12.031200
Sample Run #2 Incorrect and unexpected output
Enter float value 324.123
Value = 324.122986
Sample Run #3 Incorrect and unexpected output
Enter float value 945.1234
Value = 945.123413
I don't know why the system is adding some garbage values at the end. I am using GNU GCC compiler in code::blocks.
Your float cannot represent every conceivable number exactly. It has limitations. The closest float to "324.123" is 324.122986...
If you need more precision, use double, but even that has its limits too.
A float will be correct (match similarly limited input) to at least FLT_DIG significant digits. To print a number to FLT_DIG significant digits use:
printf("%.*e", FLT_DIG - 1, num);
FLT_DIG is at least 6.
number of decimal digits, q, such that any floating-point number with q decimal digits can be rounded into a floating-point number with p radix b digits and back again without change to the q decimal digits, ... C11dr §5.2.4.2.2 11
printf("Value = %f", num);
It will add some value if like :
Enter float value 945.1234
Value = 945.123413
because float value always print a 6 digit after the decimal point
to avoid this you can use the statement like :
printf("Value = %.3f", num);
This Will Give You A desire output as you want
it will print only three number after the decimal point
you can set as per your requirement like
"%.2f" ->for 2 number after the decimal
"%.3f" ->for 3 number after the decimal
"%.4f" ->for 4 number after the decimal

Why does this C computation involving exponents produce the wrong answer? [duplicate]

This question already has answers here:
C program to convert Fahrenheit to Celsius always prints zero
(6 answers)
Closed 9 years ago.
I am trying to implement the below formula on C
Here is my code:
int function(int x){
return pow(10, (((x-1)/(253/3))-1));
}
int main(void){
int z = function(252);
printf("z: %d\n",z);
return 0;
}
it outputs 10. However a calculator outputs 94.6.
could anyone explain me what I am doing wrong?
Note that in this line
(((x-1)/(253/3))-1))
You are dividing the integer value x - 1 by an integer value 253 / 3. This will truncate the value to an int, meaning that you'll be raising an integer power to an integer power.
To fix this, try changing this expression to
(((x-1)/(253.0 / 3.0))-1))
This now will use doubles in the expression, giving you the value you want.
Hope this helps!
Adding to that, integers do not give you the decimal part of numbers, so a number like 3.5 will get cut down to 3 using integer. To fix this double is the way to go. In other words 3 is different than 3.0

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