#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
为什么结果不一致,某些类型产生-10,其他类型产生巨大价值?
答案 0 :(得分:13)
一元-
运算符的操作数是提升;比int
更窄的类型被提升为int
或unsigned int
。
由于(已签名)int
可以包含unsigned char
可以表示的所有值,因此值(unsigned char)10
会提升为已签名 {{ 1}}值int
。否定为您提供(签名)10
值int
,然后将其转换为-10
。
double
未被“提升”为unsigned int
,因为int
无法保存所有值。因此表达式int
应用-e
否定运算符,这显然不会产生负值。结果为unsigned int
,您的系统上的结果为UINT_MAX + 1 - 10
。转换为4294967286
会产生您看到的值。
同样,double
未升级,因此unsigned long
会产生-f
,转换为ULONG_MAX + 1 - 10
时会产生double
(2 64 -10)(显然你的系统有64位18446744073709551606
和long
)。将该值转换为unsigned long
会失去一些精确度,从而产生您看到的值。
除了促销规则之外,重要的是要记住C表达式的类型(几乎总是)不受其出现的上下文的影响。 double
生成相同值和类型的结果,无论它分配给什么。