有符号整数的算术右移

时间:2016-03-30 14:30:11

标签: c c99 bit-shift

C99规范声明:

  

E1>的结果> E2是E1右移E2位位置。如果E1具有无符号类型或者E1具有有符号类型和非负值,则结果的值是E1 / 2 ^ E2的商的整数部分。如果E1具有有符号类型和负值,则结果值是实现定义的。

我很想知道哪些实现/编译器不会将签名的E1 >> 31视为一堆11111....

2 个答案:

答案 0 :(得分:2)

大多数用于微控制器的嵌入式编译器倾向于采用逻辑移位(零移位)而不是算术移位(符号位移位)。

这可能是因为签名数字在嵌入式系统中有点罕见,因为这种编程比使用屏幕的桌面编程更接近硬件并且远离用户。

签名号码毕竟只是用户演示。如果您不需要向用户打印数字,那么您根本不需要经常签名的数字。

当然,开始使用有符号数字的移位并没有任何意义。我从未在编程生涯中遇到过需要这样做的情景。在大多数情况下,这种转变只是偶然的错误。

答案 1 :(得分:0)

您可以使用无符号类型模拟带符号的2&2补码算术右移,而无需使用if语句。例如:

#include <limits.h>

unsigned int asr(unsigned int x, unsigned int shift)
{
    return (x >> shift) | -((x & ~(UINT_MAX >> 1)) >> shift);
}

您可能需要在代码中使用不同的无符号类型及其关联的最大值。