当您将位移过值的末尾时,F#中的位移运算符为documented,因为它不进行旋转。你可以在F#Interactive中看到这个:
> let a = 128uy - a <<< 1;; val a : byte = 128uy val it : byte = 0uy
也就是说,我们将高位从128的顶部移开,得到0。
如果F#旋转位而不是将它们移到末尾,我们就会得到1,因为MSB位置的1位会向下旋转到LSB。
但是,如果对第二个语句进行少量更改,则会得到一个令人惊讶的结果:
> let a = 128uy - a <<< 8;; val a : byte = 128uy val it : byte = 128uy
现在它看起来完全旋转了字节中的位!
为什么会这样?
答案 0 :(得分:3)
这里发生的事情是F#在进行移位之前对位移运算符右侧的值进行modular arithmetic。对于无符号字节,它使用mod
8,因为F#字节中有8位。由于8 mod
8为0,因此根本不会移位字节中的位。
如果您稍微使用这些值,您可以更清楚地看到这一点:
> let a = 4uy - a <<< 1;; val a : byte = 4uy val it : byte = 8uy > a <<< 9;; val it : byte = 8uy > a <<< 17;; val it : byte = 8uy
我们在所有三种情况下得到相同的结果,因为它们是mod
8中的等效表达式。
右移(>>>
)也会发生同样的事情,行为不仅限于字节。