c语言的printf输出浮点数的一些问题
在printf时:如果以%f格式输出,将输出8个字节(scanf输入时,%f是4个字节)
在参数入栈时如果是float型或者double型 直接入栈8个字节,此时输出及后续输出都没问题
但如果参数小于8个字节且不是float型:比如int shor int ,就会扩展符号位,成为4个字节再入栈,但是输出的是8个字节,所以会读取其他参数的入栈结果
#include <stdio.h> #include <stdlib.h> #include <string.h> int main(int argc, const char *argv[]) { int a = 3; int b = 5; printf("%f %d\n", a, b); return 0; }
在linux下的gcc输出结果是: 0.000000 134513801 -->后面这个值是一个无用值,比如int x; printf("%d\n", x) -->输出的就是:134513801
在vs2013下的输出结果是:0.000000 0 vs中对int x; printf("%d\n",x)会出现错误,因为x未初始化,
-->上述入栈结果是(十六进制):
栈顶 栈底
03 00 00 00 05 00 00 00
-->%f 读取8个字节,直接把b的入栈结果读走了
符号位 阶码 尾数 总位数
短浮点数 1 8 23 32
长浮点数 1 11 52 64
在32位浮点数的读取中:从内存中读出0x 03 00 00 00后,因为是小端模式,所以变成0x 00 00 00 03
0 000 0000 0 000 0000 0000 0000 0000 0011
第一个0是符号位:表正
第2到9位是阶码,32位浮点数的指数偏移量是127, 所以此处是-127
后面的均为小数点后面的:小数点前为1
-->(1 + 2^(-22) + 2^(-23)) * 2^(-127)
趋近于0;
在64位浮点数中:则阶码偏移量为:2^(10) - 1
例1:
#include <stdio.h> #include <stdlib.h> #include <string.h> int main(int argc, const char *argv[]) { int a = 3; int b = 0xffffffff; printf("%f %d\n", a, b); return 0; }
在gcc中结果为:-nan 134513801 -->-nan表示负无穷大
在VS2013中结果为:-1.#QNAN0 0
printf的栈中: 03 00 00 00 ff ff ff ff
-->按%f读取的时候:ff ff ff ff 00 00 00 03
-->按浮点数解析相应的位!
例2:
#include <stdio.h> #include <stdlib.h> #include <string.h> int main(int argc, const char *argv[]) { int a = 0x10000003; int b = 0x40110000; printf("%f %d\n", a, b); int c[2]; c[0] = 0x10000003; c[1] = 0x40110000; double d = *(double*)c; printf("%f\n", d); return 0; }
gcc中:
分析:
在第一个printf的栈中: 03 00 00 10 00 00 11 40
-->以%f读出时出栈结果:0x 40 11 00 00 10 00 00 03
-->64位浮点数解析:0100 0000 0001 0001 0000 0000 0000 0000 0001 0000 0000 0000 0000 0000 0000 0011
符号位:0
阶码:100 0000 0001 -->11位 -->减去偏移量:2^(10) -1 -->结果为2
小数位:0001 0000 0000 0000 0000 00....
最后大小:(1 + 2^(-4) + 2^(-52) + 2^(-51) + 2^(-24)) * 2^(2)
-->2进制:100 + 2^(-2) -->4.250000
#include <stdio.h> #include <stdlib.h> #include <string.h> int main(int argc, const char *argv[]) { int a = 5; float b = 3.0; printf("%d %d\n" , a, b); return 0; }
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。