#include "stdio.h" int main() { int x = -13701; unsigned int y = 3; signed short z = x / y; printf("z = %dn", z); return 0; }
我希望答案是-4567。 我得到“z = 17278”。 为什么推广这些数字导致17278?
我在Code Pad中执行了这个。
隐藏类型转换是:
signed short z = (signed short) (((unsigned int) x) / y);
混合有符号和无符号类型时,未签名的类型会赢。 x
被转换为unsigned int
,除以3,然后将该结果下转换为(signed) short
。 使用32位整数:
(unsigned) -13701 == (unsigned) 0xFFFFCA7B // Bit pattern (unsigned) 0xFFFFCA7B == (unsigned) 4294953595 // Re-interpret as unsigned (unsigned) 4294953595 / 3 == (unsigned) 1431651198 // Divide by 3 (unsigned) 1431651198 == (unsigned) 0x5555437E // Bit pattern of that result (short) 0x5555437E == (short) 0x437E // Strip high 16 bits (short) 0x437E == (short) 17278 // Re-interpret as short
顺便说一句, signed
关键字是不必要的。 signed short
是一种较长的说short
。 唯一需要显式signed
类型是char
。 char
可以根据平台签名或签名; 默认情况下,所有其他类型始终签名。
简短回答:该部门首先将x
提升为unsigned
。 只有这样才能将结果转回signed short
。
答案很长:读这个SO线程。
问题来自unsigned int y
。 实际上, x/y
变为无符号。 它适用于:
#include "stdio.h" int main() { int x = -13701; signed int y = 3; signed short z = x / y; printf("z = %dn", z); return 0; }
每次在加法和乘法算术运算中混合“大”有符号和无符号值时,无符号类型“获胜”,并且在无符号类型的域中执行求值(“大”表示int
和更大)。 如果您的原始签名值为负数,则首先会根据签名到无符号转换的规则将其转换为正无符号值。 在您的情况下-13701
将变为UINT_MAX + 1 - 13701
,结果将用作被除数。
请注意,在典型的32位int
平台上进行有符号无符号转换的结果将导致无符号值4294953595
。 除以3
你会得到1431651198
。 此值太大,无法强制进入16位short
类型平台上的short
对象。 尝试这样做会导致实现定义的行为。 因此,如果您的平台的属性与我的假设相同,那么您的代码会产生实现定义的行为。 从forms上讲,您获得的“无意义” 17278
值只不过是该实现定义行为的特定表现forms。 有可能,如果您编译了启用了溢出检查的代码(如果您的编译器支持它们),它将陷入分配。
以上就是c/c++开发分享发生了什么类型的转换?相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注计算机技术网(www.ctvol.com)!)。
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/c-cdevelopment/550030.html