#include<stdio.h>
int main(void)
{
int x=3;
float y=9.0f;
printf("%f %d\n", x, y);
printf("%d %f\n", y, x);
return 0;
}
我以为 两个printf 输出 结果, 是一样的,但是 事实 并不一样, 这编译器 到底是怎么搞的啊?
有 哪位高手 指点下, 为什么两个printf 输出 结果不是一样的?
6 个解决方案
#1
这是因为,int和float在内存中的存储模式不同(比如int的9 和 float的9.0 在内存中的表现是完全不同的)
而printf这种不定量参数的函数,对于参数的识别是完全依照第一个""中的模式来进行匹配的,而不会对后续的x,y进行类型转换,直接将内存内容原封不动的传递过去,就会出现显示上的错误
而printf这种不定量参数的函数,对于参数的识别是完全依照第一个""中的模式来进行匹配的,而不会对后续的x,y进行类型转换,直接将内存内容原封不动的传递过去,就会出现显示上的错误
#2
我关于这个问题写了一篇文章,请参看
http://blog.csdn.net/happymawolf/archive/2011/04/16/6327776.aspx
http://blog.csdn.net/happymawolf/archive/2011/04/16/6327776.aspx
#3
因此,这种情况下需要程序员自己对参数进行显式的类型转换操作,如下:
#include<stdio.h>
int main(void)
{
int x=3;
float y=9.0f;
printf("%f %d\n", x, y);
printf("%d %f\n", (int)y, (float)x);
return 0;
}
#4
#5
ls 讲完了,支持
#6
我晕, 你得先搞懂int与float的数据格式
作为 int,小端系统是这样存放的,例如9 : 0x09 0x00 0x00 0x00
作为 float, 小端是这样存放的 00 00 10 41
int 不解释!
float 根据 ieee745 标准 为 符号位1, 8位阶码,移码表示, 23位尾数, 尾数去掉开头的1(可以多表示1位)
我们吧 00 00 10 41 按照大端 分解成为2进制 41 10 00 00
就是 0 10000010 001 0000 0000 0000 0000 0000
再来分析浮点数+9.0f 转换位2进制为 01001, 符号位为0。 1001 变成 规格化的 小数 是 1.001 * 2^3, 去掉首位的1,就变成了
.001 * 2^3 那么可以确定符号位 0, 尾数位 001 0000 0000 0000 0000 0000
阶码为3,对它取移码, 127 + 3 = 130 二进制位 1000 0010
正好吻合,
所以你用按照int型打印float时 就是 打印出 0x41100000, 即十进制的 1091567616
按照 09 00 00 00 打印 float值时 就是不一样的值了
作为 int,小端系统是这样存放的,例如9 : 0x09 0x00 0x00 0x00
作为 float, 小端是这样存放的 00 00 10 41
int 不解释!
float 根据 ieee745 标准 为 符号位1, 8位阶码,移码表示, 23位尾数, 尾数去掉开头的1(可以多表示1位)
我们吧 00 00 10 41 按照大端 分解成为2进制 41 10 00 00
就是 0 10000010 001 0000 0000 0000 0000 0000
再来分析浮点数+9.0f 转换位2进制为 01001, 符号位为0。 1001 变成 规格化的 小数 是 1.001 * 2^3, 去掉首位的1,就变成了
.001 * 2^3 那么可以确定符号位 0, 尾数位 001 0000 0000 0000 0000 0000
阶码为3,对它取移码, 127 + 3 = 130 二进制位 1000 0010
正好吻合,
所以你用按照int型打印float时 就是 打印出 0x41100000, 即十进制的 1091567616
按照 09 00 00 00 打印 float值时 就是不一样的值了
#1
这是因为,int和float在内存中的存储模式不同(比如int的9 和 float的9.0 在内存中的表现是完全不同的)
而printf这种不定量参数的函数,对于参数的识别是完全依照第一个""中的模式来进行匹配的,而不会对后续的x,y进行类型转换,直接将内存内容原封不动的传递过去,就会出现显示上的错误
而printf这种不定量参数的函数,对于参数的识别是完全依照第一个""中的模式来进行匹配的,而不会对后续的x,y进行类型转换,直接将内存内容原封不动的传递过去,就会出现显示上的错误
#2
我关于这个问题写了一篇文章,请参看
http://blog.csdn.net/happymawolf/archive/2011/04/16/6327776.aspx
http://blog.csdn.net/happymawolf/archive/2011/04/16/6327776.aspx
#3
因此,这种情况下需要程序员自己对参数进行显式的类型转换操作,如下:
#include<stdio.h>
int main(void)
{
int x=3;
float y=9.0f;
printf("%f %d\n", x, y);
printf("%d %f\n", (int)y, (float)x);
return 0;
}
#4
#5
ls 讲完了,支持
#6
我晕, 你得先搞懂int与float的数据格式
作为 int,小端系统是这样存放的,例如9 : 0x09 0x00 0x00 0x00
作为 float, 小端是这样存放的 00 00 10 41
int 不解释!
float 根据 ieee745 标准 为 符号位1, 8位阶码,移码表示, 23位尾数, 尾数去掉开头的1(可以多表示1位)
我们吧 00 00 10 41 按照大端 分解成为2进制 41 10 00 00
就是 0 10000010 001 0000 0000 0000 0000 0000
再来分析浮点数+9.0f 转换位2进制为 01001, 符号位为0。 1001 变成 规格化的 小数 是 1.001 * 2^3, 去掉首位的1,就变成了
.001 * 2^3 那么可以确定符号位 0, 尾数位 001 0000 0000 0000 0000 0000
阶码为3,对它取移码, 127 + 3 = 130 二进制位 1000 0010
正好吻合,
所以你用按照int型打印float时 就是 打印出 0x41100000, 即十进制的 1091567616
按照 09 00 00 00 打印 float值时 就是不一样的值了
作为 int,小端系统是这样存放的,例如9 : 0x09 0x00 0x00 0x00
作为 float, 小端是这样存放的 00 00 10 41
int 不解释!
float 根据 ieee745 标准 为 符号位1, 8位阶码,移码表示, 23位尾数, 尾数去掉开头的1(可以多表示1位)
我们吧 00 00 10 41 按照大端 分解成为2进制 41 10 00 00
就是 0 10000010 001 0000 0000 0000 0000 0000
再来分析浮点数+9.0f 转换位2进制为 01001, 符号位为0。 1001 变成 规格化的 小数 是 1.001 * 2^3, 去掉首位的1,就变成了
.001 * 2^3 那么可以确定符号位 0, 尾数位 001 0000 0000 0000 0000 0000
阶码为3,对它取移码, 127 + 3 = 130 二进制位 1000 0010
正好吻合,
所以你用按照int型打印float时 就是 打印出 0x41100000, 即十进制的 1091567616
按照 09 00 00 00 打印 float值时 就是不一样的值了