【问题标题】:By Left Shifting, can 1 be set to Zero通过左移,可以将 1 设置为零
【发布时间】:2021-02-11 11:46:57
【问题描述】:

我对左移运算符和 1 感到困惑

int a =1;
cout<<"size of int: "<<sizeof(int)<<endl;
cout <<(a<<31)<<endl;
cout <<(a<<32)<<endl;

结果:

size of int: 4 -2147483648 1

如果我向左移动 32 或 33,它会打印 1。 如何以及为什么它是 1,如果我想左移 1 为零,我该怎么做? 谢谢。

【问题讨论】:

    标签: c++ c binary bit-manipulation bit-shift


    【解决方案1】:

    不允许将位值 1 移入有符号整数的符号位。这样做是undefined behavior。如果您这样做,编译器不能保证产生任何特定的结果。

    类似地,移位大于或等于相关整数的位宽,无论有符号还是无符号,也会引发未定义的行为。

    C standard 的第 6.5.7 节第 2 和第 3 段关于按位移位运算符状态:

    3 整数提升在每个操作数上执行。结果的类型是提升的左操作数的类型。 如果右操作数的值为负数或大于或等于提升的左操作数的宽度,则行为未定义。

    4 E1 &lt;&lt; E2 的结果是E1 左移E2 位位置;空出的位用零填充。如果E1 具有无符号类型,则结果的值为E1×2E2,比结果类型中可表示的最大值多模1。 如果E1 有一个有符号类型和非负值,并且 E1×2E2 在结果类型中是可表示的,那么这就是结果值;否则,行为未定义。

    【讨论】:

    • 感谢您的有用回答!但是,当您说“移动大于或等于所讨论整数的位宽的量”时,我有另一个困惑,如果量等于 1(完全 1
    • @Anhken 它未定义的行为,因为你左移一个负数。 UB 可以证明自己的方式之一是事情似乎按预期工作。但同样,不能保证这一点。您可以进行看似无关的更改,突然之间您会得到不同的结果。
    • 我还有一个愚蠢的问题,相同的 int a = a^32-1 如果我移动而不是 1 我向左移动 2(以避免负数) 它仍然是未定义的行为吗?感谢您的耐心等待。
    • @Anhken 已经是负数了。移动不同的量不会改变这一点。
    • 哦,所以我知道我的问题,我对你说的负数没有足够的了解。你能给我一些链接来了解你所说的二进制系统中的负数吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多