2010-02-22 4 views
14

이것은 프로그래밍 문제가 아닌 언어 디자인에 가깝습니다. 왼쪽 피연산자의 촉진 종류 만 오른쪽 피연산자의 다섯 최하위 비트가 이동량으로서 사용된다 int 인 경우C#/Java와 같은 고급 언어가 비트 시프트 수 피연산자를 마스크하는 이유는 무엇입니까?

:

다음 JLS 15.19 Shift Operators에서 발췌 .

왼쪽 피연산자의 수준 올리기 유형이 long 인 경우 오른쪽 피연산자의 하위 6 자리 비트 만 이동 거리로 사용됩니다.

이 동작

specified in C#이며, (거기에 하나의 경우) 자바 스크립트의 공식 스펙에 있는지 잘 모르겠어요 동안, 적어도 내 자신의 테스트를 기반으로 또한 사실이다.

이동 때이 규격은 기본 하드웨어 만 카운트 피연산자에 5 비트 걸린다는 사실에 의해 아마 "영감"이라고 이해
(1 << 32) == 1 

32 비트 :

결과는 다음에 해당하는 것입니다 값 (예 : 64 비트의 경우 6 비트)을 사용하여 JVM 수준에서 지정된 동작을 이해할 수 있지만 C# 및 Java와 같은 고급 언어는 왜 다소 낮은 수준의 동작을 유지합니까? 하드웨어 구현을 넘어 추상적 인 관점을 제공하고보다 직관적으로 행동해야합니까? (다른 방향으로 이동하기 위해 음수를 취할 수 있다면 더 좋을 것입니다!)

답변

8

Java 및 C#은 완전히 "상위 수준"이 아닙니다. 그들은 마이크로 벤치 마크에서 빛나기 위해 효율적인 코드로 컴파일 될 수 있도록 열심히 노력합니다. 이러한 이유로 기본 정수 형식으로 올바른 정수가 아닌 고정 된 범위의 개체가 될 수있는 int과 같은 "값 형식"이 있습니다.

따라서 하드웨어가하는 것을 모방합니다. 그들은 위임 마스킹에서 C가 허용하는 것에서 조금 다듬습니다. 여전히 Java와 C#은 "중간 수준"언어입니다.

+0

언어의 수준이 높은지 아닌지에 대한 결정은 매우 주관적입니다. 그러나 대부분의 사람들은 적어도 스크립팅 언어가 아닌 경우 Java와 C#을 "높음"으로 분류 할 것이라고 생각합니다. – polygenelubricants

+0

물론입니다. 그러나 Java와 C#은 효율성을 위해서 (또는 적어도 _perceived efficiency_) 저수준 특성을 유지합니다. 32- 비트 int 형과 시프트 수 마스킹은 그러한 특성이다. Scheme과 같은 다른 언어는 그 문제에서 "상위 수준"입니다. –

+0

http://therighttool.hammerprinciple.com/statements/this-is-a-high-level-language – starblue

5

정수는 32 비트이기 때문에 정수는 32 비트입니다. 그래서 5 비트 (32 개 값을 나타 내기에 충분합니다)는 이미 전체 정수를 이동시키기에 충분합니다. 64 비트에 대해서도 비슷한 추론이 있습니다. 전체 값을 완전히 이동하려면 6 비트 만 있으면됩니다.

오른쪽의 피연산자가 32보다 큰 값으로 끝나는 계산 결과 인 경우 혼동의 일부를 이해할 수 있습니다. 마스크를 적용하는 대신 모든 비트를 이동하는 것으로 예상 할 수 있습니다.

+0

나는 왜 32 비트 값의 효과적인 시프 팅이 최대 5 비트 만 필요로하는지 이해하고, 그 이상으로는 전체 레지스터를 근본적으로 지워 버린다. 그리고 언어 사용자로서 때로는 정확히 내가 원한다. 앞에서 말했듯이 질문은 매개 변수가 왜 그런 식으로 선택되는 것이 아니라 왜 저급 언어가 고수준 언어에서 유지되는지를 설명합니다. – polygenelubricants

+0

'오른쪽 피연산자가 32보다 큰 값으로 끝나는 계산 결과 인 경우 '... 5 비트는 0 ~ 31 값을 저장할 수 있으므로 32 비트로 시프트 할 수 없으며 간단한 'xor reg, reg'가 동일한 효과를 얻을 수 있으므로 유용 할 것입니다. –

5

C# 및 Java는 shift count의 하위 비트 만 사용하는 것으로 정의합니다. 그 이유는 sparc 및 x86 shift 명령어가 수행하는 것과 마찬가지입니다. Java는 원래 Sun에서 sparc 프로세서로 구현되었으며 C#은 Microsoft에서 x86으로 구현되었습니다.

대조적으로 C/C++에서는 시프트 수가 0.31 (32 비트 정수의 경우) 범위 내에 있지 않으면 시프트 명령어의 동작을 정의되지 않은 상태로 둡니다. 그 이유는 C가 처음 구현되었을 때 다른 핸드웨어가이를 다르게 처리했기 때문입니다. 예를 들어, VAX에서 음수로 시프 팅하면 다른 방향으로 이동합니다. 따라서 C로 컴파일러는 하드웨어 시프트 명령어를 사용하여 수행 할 작업을 수행 할 수 있습니다.

관련 문제