Jag*_*gan 2 c floating-point formatting printf
int main()
{
double i=4;
printf("%d",i);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
谁能告诉我为什么这个程序输出0?
Jon*_*rdy 19
当您double使用该值创建初始化时4,其64位根据IEEE-754标准填充双精度浮点数.浮点分为三个部分:符号,指数和分数(也称为有效数,系数或尾数).符号是一位,表示该数字是正数还是负数.其他字段的大小取决于数字的大小.要解码数字,使用以下公式:
1. 分数 ×2 指数 - 1023
在您的示例中,符号位为0,因为数字为正,小数部分为0,因为数字初始化为整数,而指数部分包含值1025(2,偏移量为1023).结果是:
1.0×2 2
或者,正如您所料,4.数字的二进制表示(分为部分)如下所示:
0 10000000001 0000000000000000000000000000000000000000000000000000
或者,以十六进制表示0x4010000000000000.将值传递给printf使用说明%d符时,它会尝试sizeof(int)从传递给它的参数中读取字节.在你的情况下,sizeof(int)是4,或32位.由于您提供的64位浮点数的第一个(最右边)32位是全部0,因此它可以printf产生0整数输出.如果你要写:
printf("%d %d", i);
Run Code Online (Sandbox Code Playgroud)
然后你可能得到0 1074790400,第二个数字相当于0x40100000.我希望你明白为什么会这样.其他答案已经解决了这个问题:使用%f格式说明符并printf正确接受你的double.
Jon Purdy向您详细解释了为什么您会看到这一特定结果.但是,请记住,语言标准明确地未定义该行为:
7.19.6.1.9:如果转换规范无效,则行为未定义.248) 如果任何参数不是相应转换规范的正确类型,则行为未定义.
(强调我的)"未定义的行为"的意思
3.4.3.1:使用不可移植或错误的程序结构或错误数据时的行为,本国际标准不对此要求
IOW,编译器没有义务产生有意义或正确的结果.最重要的是,您不能依赖可重复的结果.无法保证此程序在其他平台上输出0,或者甚至在具有不同编译器设置的同一平台上输出0(可能会,但您不想依赖它).