我知道以下
unsigned short b=-5u;
由于下溢,计算 b 为 65531,但我不明白 5u 在转换为 -5 之前是否转换为有符号整数,然后重新转换回无符号以存储在 b 中或 -5u 等于 0 - 5u (应该不是这样,-x 是一元运算符)
5u
是一个文字无符号整数,-5u
是它的否定。对无符号整数的否定定义为从 2**n 中减去,其结果与从零包装减法的结果相同。
5u
是一个单一的标记,一个具有类型的右值表达式unsigned int
。-
根据无符号算术规则(算术模 2^n,其中n是无符号类型的位数)对其应用一元运算符。结果转换为unsigned short
; 如果它们不适合(并且它们不会 if sizeof(int) > sizeof(short)
),则转换也将使用模算术完成(模 2^n,其中n是目标类型中的位数)。
可能值得注意的是,如果原始参数具有 type unsigned
short
,则实际步骤是不同的(尽管结果总是相同的)。因此,如果你写过:
unsigned short k = 5;
unsigned short b = -k;
第一次操作将取决于短的大小。如果短裤小于整数(通常,但并非总是如此),第一步是提升
k
为int
. (如果 short 和 int 的大小相同,则第一步是提升k
为unsigned int
;从那时起,一切都如上所示。)根据有符号整数算术的规则,一元-
将应用于 this int
(因此,导致值为 -5)。结果 -5 将unsigned short
使用模算术隐式转换为 ,如上所述。
一般来说,这些区别没有什么区别,但在你可能有一个整数值的情况下INT_MIN
,它们可以;在 2 的补码机器上-i
,其中i
的类型int
和值INT_MIN
是实现定义的,并且在以后转换为无符号时可能会导致奇怪的值。
ISO/IEC 14882-2003 第 4.7 节说:
"If the destination type is unsigned, the resulting value is the least unsigned integer congruent to the source integer (modulo 2^n where n is the number of bits used to represent the unsigned type). [ Note: In a two’s complement representation, this conversion is conceptual and there is no change in the bit pattern (if there is no truncation). —end note ]
技术上不是下溢,只是-5
当显示为无符号数时有符号值的表示。请注意,有符号和无符号数字具有相同的“位”——它们只是显示方式不同。如果要将值打印为有符号值[假设它使用符号位扩展以填充剩余位],它将显示 -5。[这里假设它是使用 2s 补码的典型机器。C 标准不需要这样,signed
并且unsigned
类型是相同的位数,也不是计算机使用 2s 补码来表示有符号数 - 显然,如果它不使用 2s 补码,它将与您显示的值不匹配,所以我假设您的是一个 2s 补码机——它是所有常见的处理器,例如 x86、68K、6502、Z80、PDP-11、VAX、29K、8051、ARM、MIPS。但从技术上讲,C 没有必要正常运行]
当您使用一元运算符-x
时,它的效果与0-x
[这适用于计算机和数学 - 它具有相同的结果] 相同。