比特移位限制



我正试图根据CIDR表示法eq./8创建一个子网掩码。这意味着8个前导位将是1。我通过左移(这里使用32位((uint)(0xffffffff << (32-8))来实现这一点。

代码运行良好,直到我得到/0掩码,该掩码导致代码(uint)(0xffffffff << 32)

现在,左移(uint)(0xffffffff << 31)如预期的10000000.00000000.00000000.00000000那样工作。

但左移CCD_ 7得到CCD_。而预期结果为00000000.00000000.00000000.00000000

解决这个问题最简单的方法是什么?用if语句处理/0并将其全部设置为0?

来自文档:

左移操作丢弃结果类型范围之外的高阶位,并将低阶空位位置设置为零

这意味着对于32位类型的左移位,只取移位计数中的低5位。由于32=0b10_0000需要6个比特来存储,并且在屏蔽掉低5个比特之后,它将变为零。所以0xffffffff << 32相当于0xffffffff << 0

要解决这个问题,你要么需要转换成更高精度的

return (uint)(((1UL << mask) - 1) << (32 - mask))

或在转移之前检查转移计数

return mask == 0 ? 0xFFFFFFFFU : 0xFFFFFFFFU << (32 - mask);

后者在32位平台上更好

我认为正确的算法应该是:

0xffffffff & (uint)((((ulong)0x1 << mask) - 1) << (32-mask))

其中mask是/之后的数字

我在这里用c#实现了它(因为您没有指定语言(,并且似乎可以工作:https://dotnetfiddle.net/j1IfZP

相关内容

  • 没有找到相关文章

最新更新