【问题标题】:Undoing shifts without truncating在不截断的情况下撤消班次
【发布时间】:2018-04-13 23:51:18
【问题描述】:

我对此有点困惑。值不应该在移位后截断吗?

有人知道为什么会这样吗?

long a, b, c, n;
//assign any value to a, set b and c to 0x000...0

n = 128; //any number works;
b = a << n;
c = b >> n;

a == (b >> n); // True
a == c; //True;

后记

我一直都明白,如果您在任何方向移动缓冲区,“落在”缓冲区大小之外的值都会被截断,并且除非您从原始缓冲区中获取它们,否则它们基本上会丢失。 对于我在汇编中使用过的每个平台都是如此,我认为这会扩展到更高级别的语言。

但是,在 c++ 中,我可以将缓冲区(int 或 long)移动比它可以容纳的更多位,如果我然后向相反方向移动,结果等于原始“缓冲区”。

【问题讨论】:

标签: c++ bitwise-operators bit-shift


【解决方案1】:

查看Godbolt 的简化示例:

long left_shift(unsigned long a) {
    return (a << 128);
}

long right_shift(unsigned long a) {
    return ((a << 128) >> 128);
}

我们得到如下所示的程序集(gcc-7.3.0,-O2):

left_shift(unsigned long):
  xor eax, eax
  ret
right_shift(unsigned long):
  xor eax, eax
  ret

正如 HolyBlackCat 所说,这是未定义的行为。 gcc 通过将移位的结果视为 0 来实现它,即使在 right_shift 函数中我们可以从逻辑上推断出结果。 clang 在left_shift 函数中什么都不做,这也是完美的cromulent。

【讨论】:

    【解决方案2】:

    看起来 C 编译器的工作方式有点奇怪,但它绝对合理
    如果移位数大于操作数长度(以位为单位),则编译器将其除以操作数长度并使用提醒作为移位数

    // A << N
    
    L = length of A
    if L < N
        then N = A % L;
    

    因此,您可以为班次数设置这样的数字,使其撤消禁用!!!

    N = 63 可能是您的答案,对于 A 上的任何值(甚至 A=1)(A=0 除外),它都不起作用(您的条件为 FALSE)(A=0 除外)

    PUT [61 [60 ...

    试试这段代码来了解发生了什么

    #include <cstdlib>
    #include <cstdio>
    
    using namespace std;
    
    void DisplayBinary(unsigned int n, int l)
    {    
        for (int i = l - 1 ; i >= 0; i--)
        {
            printf("%x", (n & (1 << i)) >> i);
        }
    }
    
    int main(int argc, char** argv)
    {
        // x = 340
        unsigned int x = 0x154;
        for (int numberOfShifts = 0; numberOfShifts < 100; numberOfShifts++) {
            printf("numberOfShifts = %d\tresult = ", numberOfShifts);
            DisplayBinary(x << numberOfShifts, 32);
            printf("\n");
        }
    
        return 0;
    }
    

    看输出:

    numberOfShifts = 0      result = 00000000000000000000000101010100
    numberOfShifts = 1      result = 00000000000000000000001010101000
    numberOfShifts = 2      result = 00000000000000000000010101010000
    numberOfShifts = 3      result = 00000000000000000000101010100000
    numberOfShifts = 4      result = 00000000000000000001010101000000
    numberOfShifts = 5      result = 00000000000000000010101010000000
    numberOfShifts = 6      result = 00000000000000000101010100000000
    numberOfShifts = 7      result = 00000000000000001010101000000000
    numberOfShifts = 8      result = 00000000000000010101010000000000
    numberOfShifts = 9      result = 00000000000000101010100000000000
    numberOfShifts = 10     result = 00000000000001010101000000000000
    numberOfShifts = 11     result = 00000000000010101010000000000000
    numberOfShifts = 12     result = 00000000000101010100000000000000
    numberOfShifts = 13     result = 00000000001010101000000000000000
    numberOfShifts = 14     result = 00000000010101010000000000000000
    numberOfShifts = 15     result = 00000000101010100000000000000000
    numberOfShifts = 16     result = 00000001010101000000000000000000
    numberOfShifts = 17     result = 00000010101010000000000000000000
    numberOfShifts = 18     result = 00000101010100000000000000000000
    numberOfShifts = 19     result = 00001010101000000000000000000000
    numberOfShifts = 20     result = 00010101010000000000000000000000
    numberOfShifts = 21     result = 00101010100000000000000000000000
    numberOfShifts = 22     result = 01010101000000000000000000000000
    numberOfShifts = 23     result = 10101010000000000000000000000000
    numberOfShifts = 24     result = 01010100000000000000000000000000
    numberOfShifts = 25     result = 10101000000000000000000000000000
    numberOfShifts = 26     result = 01010000000000000000000000000000
    numberOfShifts = 27     result = 10100000000000000000000000000000
    numberOfShifts = 28     result = 01000000000000000000000000000000
    numberOfShifts = 29     result = 10000000000000000000000000000000
    numberOfShifts = 30     result = 00000000000000000000000000000000
    numberOfShifts = 31     result = 00000000000000000000000000000000
    numberOfShifts = 32     result = 00000000000000000000000101010100 <<<===
    numberOfShifts = 33     result = 00000000000000000000001010101000
    numberOfShifts = 34     result = 00000000000000000000010101010000
    numberOfShifts = 35     result = 00000000000000000000101010100000
    numberOfShifts = 36     result = 00000000000000000001010101000000
    numberOfShifts = 37     result = 00000000000000000010101010000000
    numberOfShifts = 38     result = 00000000000000000101010100000000
    numberOfShifts = 39     result = 00000000000000001010101000000000
    numberOfShifts = 40     result = 00000000000000010101010000000000
    numberOfShifts = 41     result = 00000000000000101010100000000000
    numberOfShifts = 42     result = 00000000000001010101000000000000
    numberOfShifts = 43     result = 00000000000010101010000000000000
    numberOfShifts = 44     result = 00000000000101010100000000000000
    numberOfShifts = 45     result = 00000000001010101000000000000000
    numberOfShifts = 46     result = 00000000010101010000000000000000
    numberOfShifts = 47     result = 00000000101010100000000000000000
    numberOfShifts = 48     result = 00000001010101000000000000000000
    numberOfShifts = 49     result = 00000010101010000000000000000000
    numberOfShifts = 50     result = 00000101010100000000000000000000
    numberOfShifts = 51     result = 00001010101000000000000000000000
    numberOfShifts = 52     result = 00010101010000000000000000000000
    numberOfShifts = 53     result = 00101010100000000000000000000000
    numberOfShifts = 54     result = 01010101000000000000000000000000
    numberOfShifts = 55     result = 10101010000000000000000000000000
    numberOfShifts = 56     result = 01010100000000000000000000000000
    numberOfShifts = 57     result = 10101000000000000000000000000000
    numberOfShifts = 58     result = 01010000000000000000000000000000
    numberOfShifts = 59     result = 10100000000000000000000000000000
    numberOfShifts = 60     result = 01000000000000000000000000000000
    numberOfShifts = 61     result = 10000000000000000000000000000000
    numberOfShifts = 62     result = 00000000000000000000000000000000
    numberOfShifts = 63     result = 00000000000000000000000000000000
    numberOfShifts = 64     result = 00000000000000000000000101010100 <<<===
    numberOfShifts = 65     result = 00000000000000000000001010101000
    numberOfShifts = 66     result = 00000000000000000000010101010000
    numberOfShifts = 67     result = 00000000000000000000101010100000
    numberOfShifts = 68     result = 00000000000000000001010101000000
    numberOfShifts = 69     result = 00000000000000000010101010000000
    numberOfShifts = 70     result = 00000000000000000101010100000000
    numberOfShifts = 71     result = 00000000000000001010101000000000
    numberOfShifts = 72     result = 00000000000000010101010000000000
    numberOfShifts = 73     result = 00000000000000101010100000000000
    numberOfShifts = 74     result = 00000000000001010101000000000000
    numberOfShifts = 75     result = 00000000000010101010000000000000
    numberOfShifts = 76     result = 00000000000101010100000000000000
    numberOfShifts = 77     result = 00000000001010101000000000000000
    numberOfShifts = 78     result = 00000000010101010000000000000000
    numberOfShifts = 79     result = 00000000101010100000000000000000
    numberOfShifts = 80     result = 00000001010101000000000000000000
    numberOfShifts = 81     result = 00000010101010000000000000000000
    numberOfShifts = 82     result = 00000101010100000000000000000000
    numberOfShifts = 83     result = 00001010101000000000000000000000
    numberOfShifts = 84     result = 00010101010000000000000000000000
    numberOfShifts = 85     result = 00101010100000000000000000000000
    numberOfShifts = 86     result = 01010101000000000000000000000000
    numberOfShifts = 87     result = 10101010000000000000000000000000
    numberOfShifts = 88     result = 01010100000000000000000000000000
    numberOfShifts = 89     result = 10101000000000000000000000000000
    numberOfShifts = 90     result = 01010000000000000000000000000000
    numberOfShifts = 91     result = 10100000000000000000000000000000
    numberOfShifts = 92     result = 01000000000000000000000000000000
    numberOfShifts = 93     result = 10000000000000000000000000000000
    numberOfShifts = 94     result = 00000000000000000000000000000000
    numberOfShifts = 95     result = 00000000000000000000000000000000
    numberOfShifts = 96     result = 00000000000000000000000101010100 <<<===
    numberOfShifts = 97     result = 00000000000000000000001010101000
    numberOfShifts = 98     result = 00000000000000000000010101010000
    numberOfShifts = 99     result = 00000000000000000000101010100000
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-04-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-14
    • 2019-12-13
    • 2015-04-05
    相关资源
    最近更新 更多