正在发生什么类型转换?
#include "stdio.h"
int main()
{
int x = -13701;
unsigned int y = 3;
signed short z = x / y;
printf("z = %d\n", z);
return 0;
}
我预计答案是-4567。我得到“z = 17278”。 为什么这些数字的提升结果是 17278?
我在 Code Pad 中执行了此操作。
#include "stdio.h"
int main()
{
int x = -13701;
unsigned int y = 3;
signed short z = x / y;
printf("z = %d\n", z);
return 0;
}
I would expect the answer to be -4567. I am getting "z = 17278".
Why does a promotion of these numbers result in 17278?
I executed this in Code Pad.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
隐藏的类型转换是:
当混合有符号和无符号类型时,无符号类型获胜。
x
转换为unsigned int
,除以 3,然后将该结果向下转换为(有符号)short
。对于 32 位整数:顺便说一句,
signed
关键字是不必要的。signed Short
是short
的更长表达方式。唯一需要显式signed
的类型是char
。char
可以有符号或无符号,具体取决于平台;所有其他类型始终默认签名。The hidden type conversions are:
When you mix signed and unsigned types the unsigned ones win.
x
is converted tounsigned int
, divided by 3, and then that result is down-converted to (signed)short
. With 32-bit integers:By the way, the
signed
keyword is unnecessary.signed short
is a longer way of sayingshort
. The only type that needs an explicitsigned
ischar
.char
can be signed or unsigned depending on the platform; all other types are always signed by default.简短的回答:除法首先将
x
提升为unsigned
。只有这样,结果才会被转换回有符号短
。长答案:阅读这个SO线程。
Short answer: the division first promotes
x
tounsigned
. Only then the result is cast back to asigned short
.Long answer: read this SO thread.
问题来自于
unsigned int y
。事实上,x/y
变成无符号的。它适用于:The problems comes from the
unsigned int y
. Indeed,x/y
becomes unsigned. It works with :每次在加法和乘法算术运算中混合“大”有符号和无符号值时,无符号类型“获胜”,并且在无符号类型的域中执行计算(“大”意味着
int
和更大) )。如果您的原始有符号值是负数,则它首先会根据有符号到无符号转换的规则转换为正无符号值。在您的情况下,-13701
将变为UINT_MAX + 1 - 13701
,结果将用作股息。请注意,在典型的 32 位
int
平台上,有符号到无符号转换的结果将产生无符号值4294953595
。除以3
后,您将得到1431651198
。该值太大,无法强制转换为 16 位short
类型平台上的short
对象。尝试这样做会导致实现定义的行为。因此,如果您的平台的属性与我的假设相同,那么您的代码会产生实现定义的行为。从形式上来说,您获得的“无意义”17278
值只不过是实现定义的行为的具体表现。如果您在启用溢出检查的情况下编译代码(如果您的编译器支持它们),则它可能会陷入赋值。Every time you mix "large" signed and unsigned values in additive and multiplicative arithmetic operations, unsigned type "wins" and the evaluation is performed in the domain of the unsigned type ("large" means
int
and larger). If your original signed value was negative, it first will be converted to positive unsigned value in accordance with the rules of signed-to-unsigned conversions. In your case-13701
will turn intoUINT_MAX + 1 - 13701
and the result will be used as the dividend.Note that the result of signed-to-unsigned conversion on a typical 32-bit
int
platform will result in unsigned value4294953595
. After division by3
you'll get1431651198
. This value is too large to be forced into ashort
object on a platform with 16-bitshort
type. An attempt to do that results in implementation-defined behavior. So, if the properties of your platform are the same as in my assumptions, then your code produces implementation-defined behavior. Formally speaking, the "meaningless"17278
value you are getting is nothing more than a specific manifestation of that implementation-defined behavior. It is possible, that if you compiled your code with overflow checking enabled (if your compiler supports them), it would trap on the assignment.