我正试图根据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