문제

다음을 수행하는 C 코드가 있습니다.

int nPosVal = +0xFFFF;   // + Added for ease of understanding
int nNegVal = -0xFFFF;   // - Added for valid reason

이제 시도 할 때

printf ("%d %d", nPosVal >> 1, nNegVal >> 1);

나는 얻다

32767 -32768

이것이 예상됩니까?

나는 같은 생각을 할 수 있습니다

65535 >> 1 = (int) 32767.5 = 32767
-65535 >> 1 = (int) -32767.5 = -32768

즉, -32767.5는 -32768로 반올림됩니다.

이 이해가 정확합니까?

도움이 되었습니까?

해결책

구현이 아마도 2의 보완 번호로 산술 비트 전환을 수행하는 것처럼 보입니다. 이 시스템에서는 모든 비트를 오른쪽으로 이동시킨 다음 마지막 비트의 사본으로 상단 비트를 채 웁니다. 예를 들어, INT를 32 비트로 취급하십시오.

nPosVal = 00000000000000001111111111111111
nNegVal = 11111111111111110000000000000001

교대 후, 당신은 다음과 같습니다.

nPosVal = 00000000000000000111111111111111
nNegVal = 11111111111111111000000000000000

이것을 10 진수로 다시 변환하면 각각 32767과 -32768을 얻습니다.

효과적으로, 오른쪽 이동은 부정적인 무한대로 향합니다.

편집하다: 최신 섹션 6.5.7에 따르면 초안 표준, 음수에 대한이 동작은 구현에 따라 다릅니다.

E1 >> e2의 결과는 E1 오른쪽 이동 E2 비트 위치입니다. E1이 서명되지 않은 유형을 가지고 있거나 E1이 서명 된 유형 및 음이 아닌 값을 갖는 경우 결과 값은 E1 / 2의 몫의 필수 부분입니다.E2. E1에 서명 된 유형과 음수 값이있는 경우 결과 값은 구현 정의됩니다.

그들의 진술 합리적인 이것을 위해 :

C89위원회는 K & R이 부여한 이행의 자유를 확인하여 서명 된 올바른 교대 조작을 서명 확장 할 필요가 없으며, 이러한 요구 사항은 빠른 코드를 늦출 수 있고 부호 확장 교대의 유용성은 약간의이기 때문에. (부정 ~ 아니다 두 개로 나누는 것과 동일합니다!)

따라서 이론적으로는 구현에 따라 다릅니다. 실제로, 나는 구현을 본 적이 없다 ~ 아니다 왼쪽 피연산자가 서명 될 때 산술 이동을 수행하십시오.

다른 팁

아니요, 정수로 작업 할 때 0.5와 같은 분수 번호를 얻지 못합니다. 두 숫자의 이진 표현을 볼 때 결과를 쉽게 설명 할 수 있습니다.

      65535: 00000000000000001111111111111111
     -65535: 11111111111111110000000000000001

비트가 오른쪽 비트로 이동하고 왼쪽에서 확장됩니다 (이것은 구현 의존적입니다. Trent에게 감사합니다) :

 65535 >> 1: 00000000000000000111111111111111
-65535 >> 1: 11111111111111111000000000000000

소수로 다시 변환 :

 65535 >> 1 = 32767
-65535 >> 1 = -32768

C 사양은 부호 비트가 이동했는지 여부를 지정하지 않습니다. 구현 종속입니다.

당신이 오른쪽 편이를 할 때, 가장 중요하지 않은 비트는 폐기됩니다.

0xffff = 0 1111111111111111, 0 0111 1111 11111111 = 0x7fff를 제공하는 올바른 변화

-0xffff = 1 0000 0000 0000 0001 (2s 보완), 1100000000000000 = -0x8000까지의 오른쪽 시프트

A-1 : 그렇습니다. 0xffff >> 1은 0x7fff 또는 32767입니다. -0xffff가 무엇을하는지 잘 모르겠습니다. 그것은 독특합니다.

A-2 : 이동은 나누는 것과 같지 않습니다. 원시 바이너리 작업입니다. 때로는 일부 유형의 분할에 사용될 수 있다는 것이 편리하지만 항상 동일하지는 않습니다.

C 레벨 아래에 기계에는 CPU 코어가 있습니다. 스칼라. 요즘 모든 데스크탑 CPU에는 FPU가 있지만 이것은 항상 그런 것은 아니며 오늘날에도 내장 된 시스템조차도 부동 소수점 지침없이 만들어졌습니다.

오늘날의 프로그래밍 패러다임 및 CPU 디자인 및 언어는 FPU가 존재하지 않는 시대의 날짜입니다.

따라서 CPU 지침이 구현됩니다 고정 포인트 작업, 일반적으로 순전히 처리됩니다 정수 OPS. 프로그램이 항목을 선언 한 경우에만 뜨다 또는 더블 모든 분수가 존재할 것입니다. (음, 당신은 분수가있는 "고정 지점"에 CPU OPS를 사용할 수 있지만 지금은 항상 매우 드 rare니다.)

몇 년 전 언어 표준위원회가 요구했던 것에 관계없이 모든 합리적인 기계는 서명 된 번호의 올바른 변화에 부호 비트를 전파합니다. 서명되지 않은 값의 오른쪽 이동은 왼쪽의 0에서 이동합니다. 오른쪽으로 바뀌는 비트가 바닥에 떨어집니다.

이해하기 위해서는 조사해야합니다 "TWOS- 보상 산술".

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