This question already has answers here:
Closed last year.
bit shifting with unsigned long type produces wrong results
(4个答案)
我正在尝试创建一个方法,使用一个高、一个低和一个源将一个位范围更改为所有1。代码从0到30工作,然后输出不正确的数字。setbit(0,31,0)的正确结果应该是ffffffff,而不是0。
是什么导致我的代码重置为零?
setBits(0,0,0): 1
setBits(0,1,0): 3
setBits(0,2,0): 7
setBits(0,3,0): f
setBits(0,4,0): 1f
setBits(0,5,0): 3f
setBits(0,6,0): 7f
setBits(0,7,0): ff
setBits(0,8,0): 1ff
setBits(0,9,0): 3ff
setBits(0,10,0): 7ff
setBits(0,11,0): fff
setBits(0,12,0): 1fff
setBits(0,13,0): 3fff
setBits(0,14,0): 7fff
setBits(0,15,0): ffff
setBits(0,16,0): 1ffff
setBits(0,17,0): 3ffff
setBits(0,18,0): 7ffff
setBits(0,19,0): fffff
setBits(0,20,0): 1fffff
setBits(0,21,0): 3fffff
setBits(0,22,0): 7fffff
setBits(0,23,0): ffffff
setBits(0,24,0): 1ffffff
setBits(0,25,0): 3ffffff
setBits(0,26,0): 7ffffff
setBits(0,27,0): fffffff
setBits(0,28,0): 1fffffff
setBits(0,29,0): 3fffffff
setBits(0,30,0): 7fffffff
setBits(0,31,0): 0

uint64_t setBits(unsigned low, unsigned high, uint64_t source)
{
    assert(high < 64 && (low <= high));
    uint64_t mask;
    mask = ((1 << (high-low + 1))-1) << low;
    uint64_t extracted = mask | source;
    return extracted;
}

最佳答案

您需要将初始位设置为unsigned long long(或uint64_t)类型,以便在位移位时不会溢出。

mask = ((1ULL << (high - low + 1)) - 1) << low;
          ^^^

对于int类型的数字1,当左移32位时,它将溢出:
((1 << (high-low + 1))-1) // Where (high-low + 1) == 31 - 0 + 1 == 32
  ^

    00000000 00000000 00000000 00000001 = 1
 v <-- Left shift for 32 bits --------<
(1) 00000000 00000000 00000000 00000000 = 0

但这对于64位整数类型是有效的。所以把它改成1ULL问题就解决了。

关于c - uint64_t将位范围设置为1 ,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/48436659/

10-11 21:17