有符号整数的算术右移
Arithmetic right-shift of signed integer
C99 规范指出:
The result of E1 >> E2 is E1 right-shifted E2 bit positions. If E1 has an unsigned type or if E1 has a signed type and a nonnegative value, the value of the result is the integral part of the quotient of E1 / 2^E2. If E1 has a signed type and a negative value, the resulting value is implementation-defined.
我很想知道,哪个 implementations/compilers 不会将已签名的 E1 >> 31
视为一堆 11111....
?
大多数用于微控制器的嵌入式编译器倾向于逻辑移位(零移位)而不是算术移位(符号位移位)。
这可能是因为带符号的数字在嵌入式系统中很少见,因为这样的编程比使用屏幕的桌面编程更接近硬件而远离用户。
签名的数字毕竟只是用户展示。如果您不需要向用户打印数字,那么您根本不需要经常签名数字。
当然,一开始就对有符号数使用 shift 没有任何意义。在我的编程生涯中,我从未遇到过需要这样做的情况。这意味着在大多数情况下,这种转变只是偶然的错误。
您可以使用无符号类型模拟带符号的 2 的补码算术右移,而无需使用 if
语句。例如:
#include <limits.h>
unsigned int asr(unsigned int x, unsigned int shift)
{
return (x >> shift) | -((x & ~(UINT_MAX >> 1)) >> shift);
}
您可能需要在代码中使用不同的无符号类型及其关联的最大值。
C99 规范指出:
The result of E1 >> E2 is E1 right-shifted E2 bit positions. If E1 has an unsigned type or if E1 has a signed type and a nonnegative value, the value of the result is the integral part of the quotient of E1 / 2^E2. If E1 has a signed type and a negative value, the resulting value is implementation-defined.
我很想知道,哪个 implementations/compilers 不会将已签名的 E1 >> 31
视为一堆 11111....
?
大多数用于微控制器的嵌入式编译器倾向于逻辑移位(零移位)而不是算术移位(符号位移位)。
这可能是因为带符号的数字在嵌入式系统中很少见,因为这样的编程比使用屏幕的桌面编程更接近硬件而远离用户。
签名的数字毕竟只是用户展示。如果您不需要向用户打印数字,那么您根本不需要经常签名数字。
当然,一开始就对有符号数使用 shift 没有任何意义。在我的编程生涯中,我从未遇到过需要这样做的情况。这意味着在大多数情况下,这种转变只是偶然的错误。
您可以使用无符号类型模拟带符号的 2 的补码算术右移,而无需使用 if
语句。例如:
#include <limits.h>
unsigned int asr(unsigned int x, unsigned int shift)
{
return (x >> shift) | -((x & ~(UINT_MAX >> 1)) >> shift);
}
您可能需要在代码中使用不同的无符号类型及其关联的最大值。