int main()
{
double i=4;
printf("%d",i);
return 0;
}
有人可以告诉我为什么这个程序输出0?
答案 0 :(得分:19)
当您使用值double
创建4
时,根据IEEE-754 standard填充其64位,以获得双精度浮点数。浮点分为三个部分:符号,指数和分数(也称为有效数字 >,系数或尾数)。符号是一位,表示该数字是正数还是负数。其他字段的大小取决于数字的大小。要解码数字,使用以下公式:
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);
然后你可能得到0 1074790400
,其中第二个数字相当于0x40100000
。我希望你明白为什么会这样。其他答案已经解决了这个问题:使用%f
格式说明符,printf
将正确接受您的double
。
答案 1 :(得分:8)
Jon Purdy向您详细解释了为什么您会看到这一特定结果。但是,请记住,语言标准明确 undefined :
7.19.6.1.9:如果转换规范无效,则行为未定义。 248) 如果任何参数不是相应转换规范的正确类型,则行为未定义。
(强调我的)“未定义的行为”意味着
3.4.3.1:使用不可移植或错误的程序结构或错误数据时的行为,本国际标准不对此要求
IOW,编译器没有义务产生有意义或正确的结果。最重要的是,您不能依赖可重复的结果。无法保证此程序在其他平台上输出0,或者甚至在具有不同编译器设置的同一平台上输出0(可能,但您不想依赖它)。
答案 2 :(得分:3)
%d代表整数:
int main()
{
int i=4;
double f = 4;
printf("%d",i); // prints 4
printf("%0.f",f); // prints 4
return 0;
}
答案 3 :(得分:2)
因为这种语言让你搞砸了,你很乐意这样做。
更具体地说,'%d'是int的格式,因此printf(“%d”)消耗的参数与int所占的字节数一样多。但是double要大得多,所以printf只会得到一堆零。使用'%lf'。
答案 4 :(得分:1)
由于"%d"
指定您要打印int
,但i
是double
。请改为printf("%f\n");
(\n
指定换行符。)
答案 5 :(得分:1)
正如其他人所说,简单对您的问题的回答是,您告诉printf
打印整数号码(例如变量)类型int
)虽然传递了双精度数(因为你的变量属于double
类型),这是错误的。
以下是printf(3)
linux程序员手册中解释%d
和%f
转化说明符的摘录:
d, i The int argument is converted to signed decimal notation. The
precision, if any, gives the minimum number of digits that must
appear; if the converted value requires fewer digits, it is
padded on the left with zeros. The default precision is 1.
When 0 is printed with an explicit precision 0, the output is
empty.
f, F The double argument is rounded and converted to decimal notation
in the style [-]ddd.ddd, where the number of digits after the
decimal-point character is equal to the precision specification.
If the precision is missing, it is taken as 6; if the precision
is explicitly zero, no decimal-point character appears. If a
decimal point appears, at least one digit appears before it.
要使当前代码正常工作,您可以做两件事。已经建议使用第一个替代方案 - 将%d
替换为%f
。
您可以做的另一件事是将double
投射到int
,如下所示:
printf("%d", (int) i);
更简单的答案(解决printf
行为的原因)只是由Jon Purdy简要回答。要获得更深入的解释,请查看与floating point arithmetic和double precision相关的维基百科文章。
答案 6 :(得分:0)
因为我是双重的,你告诉printf使用它就好像它是一个int(%d)。
答案 7 :(得分:0)