문제

FindBugs (광산에 통합하기 전에 조심해야 함)를 사용하여 타사 소스 코드를 스캔했으며 다음 경고를 찾았습니다.

long a = b << 32 | c

버그 : 32 패턴 ID에 의한 정수 이동 : ICAST_BAD_SHIFT_AMOUNT, 유형 : Bshift, 카테고리 : 정확성

코드는 범위 0..31 외부의 일정한 양에 의해 정수 이동을 수행합니다. 이것의 효과는 정수 값의 더 낮은 5 비트를 사용하여 얼마나 많은 변화를 결정하는지를 결정하는 것입니다. 이것은 아마도 원치 않는 것이 예상되었고 적어도 혼란 스럽습니다.

누구든지 위의 의미가 정확히 무엇을 의미하는지 설명해 주시겠습니까?

감사! (저는 Java 프로그래밍의 초보자입니다)

도움이 되었습니까?

해결책

로부터 자바 언어 사양:

왼쪽 피연산자의 프로모션 유형이 int 인 경우 오른쪽 피연산자의 가장 낮은 5 개의 비트 만 이동 거리로 사용됩니다. 마치 마스크 값 0x1f와 함께 오른쪽 오페라에 약간의 논리 및 연산자 (§15.22.1)가 적용되는 것처럼 보입니다. 따라서 실제로 사용되는 이동 거리는 항상 0에서 31의 범위에 있습니다.

따라서 B가 int 인 경우 표현식은 동일합니다.

long a = b | c;

내가 의심되는 것은 의도 된 것입니다. 아마 그랬을 것입니다

long a = ((long) b << 32) | c;

(B가 이미 길다면 코드가 정확하고 FindBugs는 버그에 대해 착각합니다).

다른 팁

편집 : 문제는 거의 확실히 'b'가 'int'이고 '긴'것이 아니라는 사실에서 비롯됩니다.

C에서 'B'가 긴 대신 정수이고 32 비트로 왼쪽으로 이동하면 원래 값의 모든 비트가 제거되었으므로 전체 표현식의 결과는 'C'와 동일합니다. 정의되지 않은 동작을 호출하므로 모든 결과가 허용됩니다. Java는 Rasmus Faber의 의견과 선택한 답변에서 언급 한 바와 같이 사물을 다르게 정의하며, 모듈로 이동할 수있는 최대 비트 수를 모듈로 이동시킵니다. [사업을하는 이상한 방법 인 것 같습니다. 나는 아마도 언어를 가지고있는 언어로 예외를 준비했을 것입니다. 그러나 그것은 명확하게 정의되어 있으며, 이는 정의가 정확히 무엇보다 중요합니다.] 표현이 평가되는 동안 64 비트에 대한 강요는 발생하지 않습니다. 표현이 완료되고 할당이 발생할 때 발생합니다.

5 비트에 대한 언급은 ... 흥미 롭습니다. 그것은 당신이 왼쪽, 예를 들어, 48 또는 이진 110000에 의해 왼쪽으로 이동하면 16으로 좌회전하는 것과 동일하다는 것을 의미합니다. 또는 대안 적으로, 'x << n' 와 같다 'x << (n % 32)'.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top