簡體   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