c语言中的类型提升和转换

Type promotion and conversion in c

本文关键字:转换 类型 语言      更新时间:2023-10-16
double dVal;
int iVal = -7;
unsigned long ulVal = 1000;
dVal = iVal * ulVal;
printf("iVal * ulVal = %lfn", dVal);

谁能一步一步解释一下如何得到4294960296000000 ?

  • 首先,将iVal的符号更改为unsigned或promotion在使用ulVal进行乘法运算之前将ulVal类型转换为?
  • 同样,如果我们将iVal和ulVal相乘,我们将超出长类型的范围我们把乘法的值存储到双变量中(这样就有了转换再一次)。但是,当双精度类型时,我们如何知道要舍入到哪个值在0附近最精确吗?从0开始的距离是多少相邻数之间的距离更大?

这真的很简单:

iVal从int提升为unsigned long。所以它的值-7(作为2的恭维)变成了一个正值0xFFFFFFF9(即。4294967289)(至少在您的特定系统上)。

当乘以1000时,会溢出unsigned long,所以结果不是4,294,967,289,000 (0x3E7 FFFFE4A8),而是0xFFFFE4A8(429960296)。

然后将其转换为double类型,得到最终答案。后面的零是因为浮点数的值略高于429960296,因为它是作为分数和构造的,printf将四舍五入到6位。

参考Joachim提到的http://en.cppreference.com/w/c/language/conversion,

首先两个整数相乘。结果存储在浮点数中。

我们看iVal * ulVal。这里我们参考常用算术转换一节。两个操作数都是整数,所以情况4。适用。

首先出现整型提升。在这里,两个操作数都是整型或更大的,因此它们是不变的。

如果提升后的类型相同,则该类型为通用类型

这是不适用的,因为类型分别是int和unsigned long。

否则,如果提升后的两个操作数具有相同的符号(都是有符号的或都是无符号的),则转换等级较低的操作数(见下文)隐式地转换为转换等级较高的操作数的类型

也不适用,因为一种类型是有符号的,另一种类型是无符号的

否则,符号性不同:如果无符号类型的操作数的转换等级大于或等于有符号类型的操作数的转换等级,则有符号类型的操作数隐式转换为无符号类型

这里的无符号操作数是long,有符号操作数是int, long的秩大于int,所以这部分适用。有符号int型被转换为无符号long型。

因此,我们有两个数4294967289(无符号长)和1000(无符号长)的乘法。做乘法会溢出,但是如果你计算4294967289000 % 2^32,你会得到4294960296

然后在等号处转换为浮点数,然后打印