c语言中的类型提升和转换
Type promotion and conversion in c
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
。
然后在等号处转换为浮点数,然后打印
- 无法转换类型 C++
- 包含可变参数包的第一个可转换类型的别名的结构
- 将 std::conditional 与不可转换类型(原始与指针)一起使用
- 链接方法时出现转换类型错误
- 如何避免隐式转换类型
- 在多重继承场景中动态强制转换类型
- 编译器不支持的转换类型
- 错误调用功能无法转换类型
- 我想看到一个在整个后缀表达式的上下文中查找转换类型 id 的示例
- 对于动态类型为强制转换类型的对象,dynamic_cast失败
- 无法在初始化中转换类型
- 如何让"auto"转换类型
- 如何通过强制转换类型指针将字符数组转换为uint16_t
- 如何从新运算符+(Template类)返回具有转换类型的对象
- 带有模板的基于枚举的工厂无法转换类型
- 使用SWIG类型映射通过字符串转换类型
- 对于可转换类型,设计比循环依赖项更好
- SWIG不能正确转换类型定义
- 将类型转换扩展到可转换类型的对/元组
- 想要将字符数组的部分转换/类型转换为值