繁体   English   中英

重复按位移位

[英]Repeated bitwise shift

我有一些代码可以从数字中提取位:

uint32_t foo = getValue(); /*this just returns a value for `foo`*/

while (foo){
    foo <<= 2;
    doSomethingWithFoo(foo);
}

我担心这里会有不确定的行为,因为我最终将“ overshifting” foo结束。 我对么?

您的代码是安全的。

这是因为多次换档的行为是明确定义的(只要每个轮换的幅度不大)。 本质上,每次迭代都从一个全新的foo开始。

如果你试图通过更多的比特以外还有一气呵成型转向才会出现的问题。

没有未定义的行为,因为位移位与数据移位的工作方式非常明确。 您可以将位移视为一个窗口,例如下面的8位值中可能有:

b7  b6  b5  b4  b3  b2  b1  b0
1   0   0   1   1   0   0   1

上面的值为十六进制的0x99。 如果要左移1,我们将得到以下结果:

b7  b6  b5  b4  b3  b2  b1  b0
0   0   1   1   0   0   1   0

这将是0x32。 如果我们要向右移一位,我们将得到以下信息:

b7  b6  b5  b4  b3  b2  b1  b0
0   1   0   0   1   1   0   0

那将是0x4C。 即使在极端情况下,我们要转移的位数是8,在这种情况下,任何超出窗口的大小都是0,因此我们知道最终将是0x00,如下所示。

b7  b6  b5  b4  b3  b2  b1  b0
0   0   0   0   0   0   0   0

因此,每种可能的情况都由该操作定义。

您可以使用圆形的左或右按位移位功能。

uint8_t circularLeftShift(uint8_t var, uint8_t numOfBits) {

    if (numOfBits < 1 || numOfBits>7) return var;

     uint8_t msb = 0;
     for (int i = 0; i < numOfBits; i++)
    {
    msb = var & 128;
    msb = msb >> 7;
    var = var << 1;
    var = var | msb;
    }
    return var; 
}



uint8_t circularRightShift(uint8_t var, uint8_t numOfBits) {

    if (numOfBits < 1 || numOfBits>7) return var;

    uint8_t lsb = 0;
    for (int i = 0; i < numOfBits; i++)
    {
        lsb = var & 1;
        lsb = lsb << 7;
        var = var >> 1;
        var = var | lsb;
    }
    return var;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM