printf ("%f\n", 5);
printf ("%d\n", 5.01);
printf ("%f\n", (float) 5);
printf ("%f\n", 5.f);
Out
0.000000
1889785610
5.000000
5.000000
It feels very strange to see the result. How can I output 0 at 1? 2 Why does it show such a large number?
Explain:
The following is an explanation of a blog that has been transferred from the Internet
1, the reason why no output 5, this is the C language design.
2, the reason for output 0, this is the problem of computer architecture.
Specifically:
The printf function does not make any type conversions, it simply reads the values of the elements you provide from memory (in the form of control character prompts, such as%d,%f). C language Design, the type of int is generally 32bit or 16bit, and float is generally 64bit, and it is possible to use scientific count to save. As Huhugo88 says, 5 is 00000000,00000101 in memory. and 5 is generally in the static zone, the program's static storage area by default is 0, then when using%f to read, will read 64bit, that is, will read a lot of bits 0, and finally according to (valid number) x (Radix 2) POW (exponent) way to take the number, the natural result is 0
This is not allowed in VCs, and some compilers allow this output to be a compiler setup problem. Supposedly, such access to memory is classified as cross-border access and should be banned. But only read, hurt a little. For single-precision floating-point numbers (32bit), many C-language compiling systems represent fractional parts (including 1bit sign bits) in 24-bit notation, with 8-bit representation of the exponential portion.
==========================printf ("%d\n", 5.01);
Why output a large number? Before talking about this topic, prepare the knowledge, say, printf function, input parameter is read into buffer to save, then follow%? Format to read data from the buffer and interpret the data in this format.
With this knowledge, you can see a question on the programmer's interview:
#include "stdio.h"
int main (int argc, char* argv[])
{
printf ("%d\n", 5.01);
return 0;
}
Output Result: 188978561
And then start to study why this number is?
5.01 is a double type, which occupies 8 bytes in memory and is saved in a buffer. While%d is an integer, accounting for 4 bytes, printf reads 4 bytes from the buffer and reads the low 32-bit data first. That is, the printf output should be 5.01 to save the number of plays in the double type of low 32 bits. To verify that the result is correct, compare 5.01 in-memory representation and output.
#include "stdio.h"
int main (int argc, char* argv[])
{
Double d = 5.01;
int *p = (int *) (&D);
int rst = 1889785610;
printf ("1).%x\n", *p);
printf ("2).%x\n", * (p+1));
printf ("3).%x\n", RST);
return 0;
}
The output is:
1). 0x70a3d70a
2). 0x40140a3d
3). 0x70a3d70a
This also proves that%d output is 5.01 lower 32 low. A double of type 5.01, in which the representation of the memory is 0x40140a3d70a3d70a.
Things seem to have been done.
I also think, if the input is a floating-point type of 5.01f, what happens?
#include "stdio.h"
int main (int argc, char* argv[])
{
float F = 5.01f;
int *p = (int *) (&F);
printf ("1). 0x%x\n", *p);
printf ("2). 0x%x\n", 5.01f);
return 0;
}
Output:
1). 0x40a051ec
2). 0x80000000
We found that the output is not a floating-point type of 5.01f memory representation, this is why?
Then there is a saying that printf will%f the output by double type, that is, the parameter float type will be converted to double type in the output.
But now is not%f, of course, using%f to show the correct results. So I guess, printf is the float type read into the data are automatically converted to double type, and then%f double processing, and we this is%d, so the display of float converted to a double type of low 4 bytes.
Verify this idea:
#include "stdio.h"
int main (int argc, char* argv[])
{
Double F = 5.01;
int *p = (int *) (&F);
printf ("1). 0x%x\n", *p);
printf ("2). 0x%x\n", * (p+1));
printf ("3). 0x%x\n", 5.01f);
return 0;
}
Output:
1). 0x70a3d70a
2). 0x40140a3d
3). 0x80000000
But we found that the results were not the same, and I guessed that it was also permissible for printf to convert float to double in a different way from the default.
The default representation of 5.01d is: 0x40140a3d70a3d70a, as explained above
#include "stdio.h"
int main (int argc, char* argv[])
{
printf ("0x%8x\n0x%8x\n", 5.01f);
return 0;
}
The output is:
0x80000000
0x40140a3d
With the expression that is found printf will 5.01f->5.01d is: 0x40140a3d80000000
The next thing to see is whether the two values are all 5.01:
#include "stdio.h"
int main (int argc, char* argv[])
{
int d1[2], d2[2];
d1[0]=0x80000000;
D1[1]=0x40140a3d;
d2[0]=0x70a3d70a;
D2[1]=0x40140a3d;
Double *P1 = (double *) D1;
Double *P2 = (double *) D2;
printf ("1).%f\n", *P1);
printf ("2).%f\n", *P2);
return 0;
}
The output is:
1). 5.010000
2). 5.010000
It also proves that 0x40140a3d80000000, and 0x40140a3d70a3d70a are both representations of 5.01d in the machine. The former is a representation of 5.01f (0X40A051EC) converted from printf to a double, the latter being the default representation of 5.01d.
Summary: printf will automatically convert the lost floating-point parameters to double, and is different from the default double-precision representation. Most important, printf unsafe, type unsafe, if the type is wrong, maybe we'll hang up ^_^
Through the above explanations, we generally understand:
1. printf output float type, will automatically convert to double type;
2. Because the storage, are the first low, then high, and after conversion to double, the front will take a lot of 0 (cross-border access);
3.5.01, when printing in accordance with int to take, only take the first four bytes.
from:http://blog.csdn.net/yahohi/article/details/7701434
printf ("%d", 5.01) and printf ("%f", 5) output results