source

C에서 음의 숫자를 이동합니다.

factcode 2023. 6. 23. 22:27
반응형

C에서 음의 숫자를 이동합니다.

저는 다음과 같은 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

이것을 다시 십진수로 변환하면 각각 32767과 -32768이 됩니다.

실질적으로 오른쪽 이동은 음의 무한대를 향해 회전합니다.

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

E1 >> E2의 결과는 E1 우변 E2 비트 위치입니다.E1에 부호 없는 유형이 있거나 E1에 부호 없는 유형과 음수가 아닌 값이 있으면 결과 값은 E1/2에 해당하는 몫의 적분 부분입니다.E2E1에 부호 있는 유형과 음수 값이 있으면 결과 값이 구현 정의됩니다.

이에 대한 그들의 진술된 합리성:

C89 위원회는 서명된 우측 이동 작업이 빠른 코드를 느리게 할 수 있고 부호 확장 이동의 유용성이 미미하기 때문에 서명된 우측 이동 작업이 서명 연장을 요구하지 않는다는 점에서 K&R이 부여한 구현의 자유를 확인했습니다.(음의 2의 보어 정수를 산술적으로 오른쪽 한 자리로 이동하는 것은2로 나누는 것과 같지 않습니다!)

따라서 이론에 따라 구현이 달라집니다.실제로, 저는 왼쪽 피연산자가 서명되었을 때 산술 시프트를 제대로 하지 않는 구현을 본 적이 없습니다.

아니요, 정수 작업을 할 때 0.5와 같은 분수를 얻을 수 없습니다.두 숫자의 이진수 표현을 보면 결과를 쉽게 설명할 수 있습니다.

      65535: 00000000000000001111111111111111
     -65535: 11111111111111110000000000000001

비트가 오른쪽으로 1비트 이동하고 왼쪽으로 확장됩니다(이것은 구현에 따라 다릅니다, Trent에게 감사합니다).

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

10진수로 다시 변환:

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

C 사양은 부호 비트의 이동 여부를 지정하지 않습니다.구현에 따라 다릅니다.

오른쪽으로 이동하면 최하위 비트가 삭제됩니다.

0xFFFF = 01111111111111111111111111111111111을 제공하는 오른쪽 방향으로 이동합니다. = 0x7FFF

-0xFFFF = 1,000,000,0001(2초 보완)이며, 1,000,000,000 = -0x8000으로 오른쪽 정렬됩니다.

A-1: 예. 0xffff >> 1은 0x7ff 또는 32767입니다.-0xffff가 무엇을 하는지 잘 모르겠습니다.특이하네요.

A-2: 이동은 나누는 것과 같은 것이 아닙니다.이는 비트 이동(원시적 이진 연산)입니다.때때로 그것이 어떤 종류의 분할에 사용될 수 있다는 것은 편리하지만 항상 같은 것은 아닙니다.

C 레벨 아래에서 시스템은 완전히 정수 또는 스칼라인 CPU 코어를 가집니다.오늘날에는 모든 데스크톱 CPU에 FPU가 있지만 항상 그런 것은 아니며 오늘날에도 임베디드 시스템은 부동소수점 명령어 없이 만들어집니다.

오늘날의 프로그래밍 패러다임과 CPU 설계 및 언어는 FPU가 존재하지 않는 시대부터 시작되었습니다.

따라서 CPU 명령어는 일반적으로 순수 정수 연산으로 취급되는 고정 지점 연산을 구현합니다.프로그램이 부동 또는 이중 항목을 선언하는 경우에만 분수가 존재합니다. (글쎄요, 분수가 있는 "고정점"에 CPU ops를 사용할 수 있지만, 그것은 현재와 항상 매우 드물었습니다.)

몇 년 전 언어 표준 위원회에서 요구한 것과 상관없이, 모든 합리적인 기계는 서명된 번호의 오른쪽 이동에 대한 부호 비트를 전파합니다.부호 없는 값의 오른쪽 이동은 왼쪽에서 0으로 이동합니다.오른쪽으로 이동한 비트는 바닥에 떨어집니다.

이해를 높이기 위해 "2-보충 산술"을 조사해야 합니다.

언급URL : https://stackoverflow.com/questions/1857928/right-shifting-negative-numbers-in-c

반응형