C++ 撤消移位而不截断

C++ 撤消移位而不截断,c++,bitwise-operators,bit-shift,C++,Bitwise Operators,Bit Shift,我对此有点困惑。值不应该在移位后截断吗 有人知道为什么会这样吗 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; 附言 我一直理解,如果你将缓冲区向任何方向移动,超出缓冲区大小的值就会被截断

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

有人知道为什么会这样吗

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或长的位移到它所能容纳的位上,如果我在相反的方向上移动,结果等于原来的缓冲区。

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

// A << N

L = length of A
if L < N
    then N = A % L;
因此,您可以设置这样的班次数,使其撤消禁用

N=63可能是您的答案,它不起作用。对于偶数A=1上的任何值,除了A=0之外,您的条件都是FALSE

放置[61 尝试此代码以了解发生了什么

#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
请使用一个简化的示例进行查看:

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

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

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

发布可以编译的代码。这是未定义的行为。看看编译器生成的汇编代码,你会在其中找到答案。另外请注意,移位有符号类型与移位无符号类型有不同的行为,特别是在右移期间。Idc关于符号,只有二进制,而且行为可以用某些值来定义,但对于大于0的任何其他值,它的行为都是相同的。没错,33到63之间的任何值都会截断这些值。谢谢这取决于a中的值,当它溢出时,看起来C编译器的工作有点奇怪…-,这个答案可能很糟糕,但至少这个答案是正确的。这个答案充其量只是误导。
left_shift(unsigned long):
  xor eax, eax
  ret
right_shift(unsigned long):
  xor eax, eax
  ret