2013-07-02 3 views
4

F #의 비트 시프트 연산자는 비트 끝을지나 비트를 이동할 때 회전하지 않으므로 documented입니다. 당신은 F # 대화에서 볼 수 있습니다F # 비트 시프트 연산자에서 360 ° 회전 "feature"

입니다
 
> let a = 128uy 
- a <<< 1;; 

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

, 우리는 (128)의 상단에 떨어져 높은 비트를 이동, 0

주는 F 번호가 아니라 말을 그들을 변화보다는 비트를 회전하면, 우리는 것 MSB 위치의 1 비트가 LSB으로 회전 할 때 1을 얻었습니다. 두 번째 문에 작은 변화를 만들 경우

그러나, 당신은 놀라운 결과를 얻을 :

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

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

지금은 바이트의 비트의 전체 회전을 할 것으로 보인다!

왜 이런가요?

답변

3

여기서 일어나는 일은 F #이 시프트를 수행하기 전에 비트 시프트 연산자의 오른쪽에있는 값에 modular arithmetic을 수행하고 있다는 것입니다. 부호없는 바이트의 경우 F # 바이트에 8 비트가 있으므로 mod 8을 사용합니다. 8 mod 8이 0이기 때문에 바이트의 비트를 전혀 이동하지 않습니다.

당신은 값을 더 명확하게 재생할 경우 약간이를 볼 수 있습니다 그들은 동등한 표현 mod 8

동일에 있기 때문에 우리는 세 가지 경우 모두에서 같은 결과를 얻을 수

 
> 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 

을 일이 우 시프트 (>>>)와 함께 발생하며 동작은 바이트로 제한되지 않습니다.

+0

이것은이 MSDN 페이지에서 설명합니다. http://msdn.microsoft.com/en-us/library/aa691377(v=vs.71).aspx –

+0

@JohnPalmer : 나에게. 첫째, F #이 아닌 C#에 관한 것입니다. C# 디자인 선택이 F #을 어떻게 제한합니까? 그 행동이 실제로 언어 컴파일러가 아닌 CLR 때문이라고 주장하고 있습니까? 둘째, 바이트 값을 전혀 회전하지 않고 32 비트 및 64 비트 정수 회전 규칙 만 설명합니다. F #의 원인이되는 것을 볼 수있는 유일한 방법은 F #에서 발생하지 않는 자동 정수 프로모션 때문에 C# 문서가이 차이를 무시하는 것입니다. –

+2

다음은'int32' (''shl "x (mask n 31))에 대한'<<<의 F # 구현을위한 코드입니다 : int #)'mask는''let inline mask (n : int) (m : int) = (# "및"nm : int #) ". 이것은 C# 연산자와 정확히 같고 '31'의 숫자와 몇 바이트 씩 이동합니다. '바이트'구현은 마스크를 변경하고 int에서 변환하는 것을 제외하고는 동일합니다. .NET은 비트 시프트 바이트를 지원하지 않습니다. –