double dVal;
int iVal = -7;
unsigned long ulVal = 1000;
dVal = iVal * ulVal;
printf("iVal * ulVal = %lf\n", dVal);
有人可以一步一步解释如何获得4294960296.000000?
答案 0 :(得分:0)
参考Joachim提到的http://en.cppreference.com/w/c/language/conversion,
首先发生两个整数的乘法运算。然后将结果存储在浮点数中。
所以我们看一下iVal * ulVal
。这里我们参考常规算术转换部分。两个操作数都是整数,所以情况4.适用。
首先发生整数促销。在这种情况下,两个操作数都是整数或更大,因此它们没有变化。
如果促销后的类型相同,则该类型为常见类型
这不适用,因为类型分别是int和unsigned long。
否则,如果升级后的两个操作数具有相同的签名(有符号或无符号),则具有较小转换等级的操作数(见下文)将隐式转换为具有较高转换等级的操作数的类型
这也不适用,因为一种类型是有符号的,第二种是无符号的
否则,签名是不同的:如果具有无符号类型的操作数的转换等级大于或等于带符号操作数的类型的等级,则带有签名类型的操作数将隐式转换为无符号类型
这里unsigned操作数是long而signed是int,long的rank大于int,所以这部分适用。 signed int将转换为unsigned long。
因此,我们将两个数字4294967289
(无符号长整数)和1000
(无符号长整数)相乘。执行乘法时会出现溢出,但如果计算4294967289000 % 2^32
,则会得到4294960296
。
然后将其转换为等号的浮点数,然后打印。
答案 1 :(得分:0)
这真的很简单:
iVal从int升级为unsigned long。所以它的值-7(是两个恭维)变成了一个正值0xFFFFFFF9(即4294967289)(至少在你的特定系统上)。
当乘以1000时,无符号长整数溢出,因此它不是4,294,967,289,000(0x3E7 FFFF E4A8)的结果,而是以0xFFFFE4A8(429960296)结束。
然后将其转换为双倍,得到你的最终答案。尾随零是因为float的值略高于429960296,因为它构造为printf舍入到6位数的分数之和。