注意:这个问题的目的是更好地理解Perl的按位运算符.我知道计算下面描述的数字U的方法.
我们$i是一个非负整数.我正在寻找一个简单的表达式E<$i>1,它将评估为无符号整数 U,其$i最低位全为1,其余位均为0.例如,E<8>应该是255.特别是,如果$i等于机器的字长(W),则E<$i>应该等于~02.
表达式(1 << $i) - 1和~(~0 << $i)两者都做正确的事情,除非$i等于W,在这种情况下它们都采用值0,而不是~0.
我正在寻找一种不需要先计算W的方法.
编辑:好的,我想到了一个丑陋,沉闷的解决方案
$i < 1 ? 0 : do { my $j = 1 << $i - 1; $j < $j << 1 ? ( $j << 1 ) - 1 : ~0 }
Run Code Online (Sandbox Code Playgroud)
要么
$i < 1 ? 0 : ( 1 << ( $i - 1 ) ) < ( 1 << $i ) ? ( 1 << $i ) - 1 : ~0
Run Code Online (Sandbox Code Playgroud)
(当然也是不切实际的.)
1我使用奇怪的符号E<$i>作为"基于表达式$i"的简写.
2我没有在时刻什么强烈的偏好E<$i>应该评估的时候$i是严格更大的比w ^.
在系统上eval($Config{nv_overflows_integers_at}) >= 2**($Config{ptrsize*8})(不包括使用双精度浮点数和 64 位整数的系统),
2**$i - 1
Run Code Online (Sandbox Code Playgroud)
在所有系统上,
( int(2**$i) - 1 )|0
Run Code Online (Sandbox Code Playgroud)
当 i<W 时,int会将 NV 转换为 IV/UV,允许减法在 NV 精度小于 UV 大小的系统上进行。|0在这种情况下没有影响。
当i≥W时,int没有效果,所以减法没有效果。|0因此会溢出,在这种情况下 Perl 返回最大的整数。
我不知道这种|0行为有多可靠。它可能是特定于编译器的。不要用这个!