带有符号 int 的位移位会重置一位太多
Bit shift with a signed int resets one bit too much
请看下面的代码片段,它基本上只是简单地将 1 个字节向左移动 24 位。
uint64_t i = 0xFFFFFFFF00000000;
printf("before: %016llX \n", i);
i += 0xFF << 24;
printf("after : %016llX \n", i);
// gives:
// before: FFFFFFFF00000000
// after : FFFFFFFEFF000000
最重要的32位是FFFFFFFE
(看最后的E
)。这不是我所期望的。我不明白为什么将 1 个字节向左移动 24 位会触及第 32 位(第 31 位应该是最后修改的)它将最后一个 F
(1111
)更改为 E
(1110
)).
为了让它正常工作,我使用了 0xFF
unsigned (0xFFU
).
uint64_t i = 0xFFFFFFFF00000000;
printf("before: %016llX \n", i);
i += 0xFFU << 24;
printf("after : %016llX \n", i);
// gives:
// before: FFFFFFFF00000000
// after : FFFFFFFFFF000000
为什么带符号的 int (0xFF
) touch/reset 位移多了一位?
你左移到了符号位。
整数常量 0xFF
的类型为 int
。假设 int
是 32 位,表达式 0xFF << 24
将设置为 1 的位移动到有符号整数触发器的高位位 undefined behavior ,在您的情况下表现为意外值。
这在 C standard 的第 6.5.7p4 节中有详细说明:
The result of E1 << E2
is E1
left-shifted E2
bit positions; vacated bits are filled with zeros. If E1
has an unsigned type, the value of the result is E1×2E2, reduced modulo one more than the maximum value representable in the result type. If E1
has a signed type and nonnegative value, and E1×2E2is representable in the result type, then that is the resulting value; otherwise, the behavior is undefined.
通过使用 U
后缀,这使得常量具有类型 unsigned int
,并且将设置为 1 的位移入高位是有效的,因为没有符号位。
请看下面的代码片段,它基本上只是简单地将 1 个字节向左移动 24 位。
uint64_t i = 0xFFFFFFFF00000000;
printf("before: %016llX \n", i);
i += 0xFF << 24;
printf("after : %016llX \n", i);
// gives:
// before: FFFFFFFF00000000
// after : FFFFFFFEFF000000
最重要的32位是FFFFFFFE
(看最后的E
)。这不是我所期望的。我不明白为什么将 1 个字节向左移动 24 位会触及第 32 位(第 31 位应该是最后修改的)它将最后一个 F
(1111
)更改为 E
(1110
)).
为了让它正常工作,我使用了 0xFF
unsigned (0xFFU
).
uint64_t i = 0xFFFFFFFF00000000;
printf("before: %016llX \n", i);
i += 0xFFU << 24;
printf("after : %016llX \n", i);
// gives:
// before: FFFFFFFF00000000
// after : FFFFFFFFFF000000
为什么带符号的 int (0xFF
) touch/reset 位移多了一位?
你左移到了符号位。
整数常量 0xFF
的类型为 int
。假设 int
是 32 位,表达式 0xFF << 24
将设置为 1 的位移动到有符号整数触发器的高位位 undefined behavior ,在您的情况下表现为意外值。
这在 C standard 的第 6.5.7p4 节中有详细说明:
The result of
E1 << E2
isE1
left-shiftedE2
bit positions; vacated bits are filled with zeros. IfE1
has an unsigned type, the value of the result is E1×2E2, reduced modulo one more than the maximum value representable in the result type. IfE1
has a signed type and nonnegative value, and E1×2E2is representable in the result type, then that is the resulting value; otherwise, the behavior is undefined.
通过使用 U
后缀,这使得常量具有类型 unsigned int
,并且将设置为 1 的位移入高位是有效的,因为没有符号位。