C++ 将无符号[char,short,int,long]转换为double的结果不一致
为什么结果不一致,某些类型的结果为-10,而其他类型的结果为巨大值?一元C++ 将无符号[char,short,int,long]转换为double的结果不一致,c++,c,C++,C,为什么结果不一致,某些类型的结果为-10,而其他类型的结果为巨大值?一元-运算符的操作数被提升;小于int的类型将升级为int或无符号int 由于(有符号)int可以保存可由无符号字符表示的所有值,因此值(无符号字符)10将提升为有符号int值10。求反得到(有符号的)int值-10,然后将其转换为双精度 unsigned int不会“升级”为int,因为int不能保存所有值。因此表达式-e应用了无符号int求反运算符,这显然不能产生负值。结果是UINT_MAX+1-10,在您的系统上是4294
-
运算符的操作数被提升;小于int
的类型将升级为int
或无符号int
由于(有符号)int
可以保存可由无符号字符表示的所有值,因此值(无符号字符)10
将提升为有符号int
值10
。求反得到(有符号的)int
值-10
,然后将其转换为双精度
unsigned int
不会“升级”为int
,因为int
不能保存所有值。因此表达式-e
应用了无符号int
求反运算符,这显然不能产生负值。结果是UINT_MAX+1-10
,在您的系统上是4294967286
。转换为double
将生成您看到的值
同样地,unsigned long
也不会升级,因此-f
产生ULONG_MAX+1-10
,当转换为double
时产生18446744073709551606
(264-10)(显然您的系统有64位long
和unsigned long
)。将该值转换为double
会损失一些精度,从而产生您看到的值
除了提升规则之外,重要的是要记住C表达式的类型(几乎总是)不受其出现的上下文的影响-f
产生相同值和类型的结果,而不管它被分配给什么。积分提升将前两个转换为更大的有符号类型(int
);对于第二个问题:只对无符号类型应用一元负号。为什么这被认为是一个糟糕的问题?我被反对票弄糊涂了。稍微解释一下为什么观察到的结果令人惊讶是有帮助的,但是关于C表达式计算的一个相当微妙的方面,这是一个有效的问题。请有人评论和解释一下好吗?@DyP我也认为这个问题很好。它是精心编写的,显示了示例代码,并描述了一个不明显的问题(一元运算符积分提升)。这是不需要使用C++中的无符号类型的原因之一,除非您需要模运算。想要禁止否定值是不够的,我听说C++委员会成员表示遗憾,他们指定标准库的部分使用该基础上的未签名类型。不应该将<代码>未签名的长< /COD>情况转换为<代码> ULUNYOXMAX + 1 - 10 < /C>(不<代码> UTIN MAX < /COD>)?我肯定这只是一个打字错误…就像关于18446744073709551606
转换为18446744073709551616.000000
的部分一样。
#include <stdio.h>
int main(int argc, char* argv[]) {
unsigned char c = 10;
unsigned short d = 10;
unsigned int e = 10;
unsigned long f = 10;
double g = -c;
double h = -d;
double i = -e;
double j = -f;
printf("%d %lf\n", c, g);
printf("%u %lf\n", d, h);
printf("%u %lf\n", e, i);
printf("%lu %lf\n", f, j);
}
10 -10.000000
10 -10.000000
10 4294967286.000000
10 18446744073709551616.000000