有谁知道 C 规范的哪一部分描述了以下行为:
以下代码片段重现了这种情况(请注意,有一些样板代码是为了避免某些不会导致问题的编译优化):
volatile int zero = 0;
unsigned int someint = 20;
if(zero == 1)
{
someint += 1;
}
double x = -someint;
编译器(clang 3.5.0,但 gcc 4.9.1 发出类似的东西)为最后一个赋值发出以下内容:
mov eax,DWORD PTR [rbp-0xc] <-- move someint in eax
neg eax
mov ecx,eax
cvtsi2sd xmm0,rcx
movsd QWORD PTR [rbp-0x18],xmm0
有趣的是,二进制补码取反(neg)是在双字(eax)上执行的,但是双字到 double 转换(cvtsi2sd) 对低 32 位为负数 -20 (mov ecx,eax) 且高 32 位全为 0 的 qword (rcx) 执行。 由于 eax 没有符号扩展到 rcx,rcx 现在包含一个正数,它在 x 之后结束转换。
另一方面,如果 someint 在赋值中被强制转换为 int,双字到 double 的转换 (cvtsi2sd) 是在双字 (ecx) 上执行,因此最终结果是 x 中预期的 -20。
最佳答案
没有“负无符号整数”这样的东西。 unsigned int 始终为正数。如果 someint = 0,你的 -someint 产生值 0,而 UINT_MAX + 1 - someint 否则根据 C 规则。改用
double x = - (double) someint;
关于c - 将负的无符号整数分配给 C 中的 double ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27612444/