Вопрос

The bit shift operators in F# are documented as not doing rotation when you shift bits past the end of the value. You can see this in F# Interactive:

> let a = 128uy
- a <<< 1;;

val a : byte = 128uy
val it : byte = 0uy

That is, we shifted the high bit off the top of 128, giving 0.

If F# rotated bits rather than shifting them off the end, we would have gotten 1 instead, as the 1 bit in the MSB position would get rotated down to the LSB.

However, if you make a small change to the second statement, you get a surprising result:

> let a = 128uy
- a <<< 8;;

val a : byte = 128uy
val it : byte = 128uy

Now it looks to have done a full rotation of the bits in the byte!

Why is this?

Это было полезно?

Решение

What's happening here is that F# is doing modular arithmetic on the value on the right hand side of the bit shift operator before doing the shift. For an unsigned byte, it uses mod 8, since there are 8 bits in an F# byte. Since 8 mod 8 is 0, it is not shifting the bits in the byte at all.

You can see this more clearly if you play with the values a bit:

> 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

We get the same result in all three cases because they are equivalent expressions in mod 8.

The same thing happens with right-shift (>>>), and the behavior isn't limited to bytes.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top