programing

K&R C 2장의 getbits() 방법 이해에 도움이 필요합니다.

padding 2023. 9. 20. 20:08
반응형

K&R C 2장의 getbits() 방법 이해에 도움이 필요합니다.

제2장 비트 와이즈 연산자 섹션(섹션 2.9)에서 샘플 방법 중 하나가 어떻게 작동하는지 이해하는 데 어려움을 겪고 있습니다.

제공되는 방법은 다음과 같습니다.

unsigned int getbits(unsigned int x, int p, int n) {
    return (x >> (p + 1 - n)) & ~(~0 << n);
}

개념은 주어진 숫자 x에 대해 오른쪽에서 세어 p 위치에서 시작하는 n개의 비트를 반환한다는 것입니다(가장 먼 오른쪽 비트는 0 위치).다음과 같은 점을main()방법:

int main(void) {
    int x = 0xF994, p = 4, n = 3;
    int z = getbits(x, p, n);
    printf("getbits(%u (%x), %d, %d) = %u (%X)\n", x, x, p, n, z, z);

    return 0;
}

출력은 다음과 같습니다.

getbits(63892 (f994), 4, 3) = 5 (5)

저는 이것의 일부를 이해하지만, 대부분 제가 이해할 수 없는 말장난(말장난이 아닌) 때문에 "큰 그림"에 어려움을 겪고 있습니다.

입니다입니다.~(~0 << n). 저는 x를 다루는 첫 번째 부분을 이해할 수 있다고 생각합니다. 제가 고심하고 있는 부분은 이 부분(그리고 마스크)입니다. 그리고 어떻게 이 부분들을 모두 모아서 실제로 그 부분들을 회수할 수 있는지입니다.(코드와 calck.exe를 사용하여 결과를 확인하는 것 모두 확인했습니다. -- 이진 보기가 있어서 다행입니다!)

도와줄 사람?

예를 들어 16비트를 사용해 보겠습니다. 땐에는.,.~0

1111111111111111

우리가 이것을 왼쪽으로 옮길 때.n비트(고객님의 경우 3), 다음을 얻을 수 있습니다.

1111111111111000

1되고 .0s는 오른쪽에 입력됩니다.그런 다음 이를 다시 보완하면 다음과 같은 이점이 있습니다.

0000000000000111

그래서 이건 단지 그들을 보호자가 될 수 있는n숫자의 가장 작은 부분에 1비트가 있습니다.

을 들어 "x" 했습니다).f994 = 1111 1001 1001 0100최소 3비트가 원하는 것이 될 정도로 충분히 멀리 있습니다.다른 다로 .최종 결과에 중요하지 않기 때문에:

ff94             ...........101..  # original number
>> p+1-n     [2] .............101  # shift desired bits to right
& ~(~0 << n) [7] 0000000000000101  # clear all the other (left) bits

보시다시피, 이제 관련 비트가 가장 오른쪽 비트 위치에 있습니다.

저는 가장 좋은 방법은 손으로 문제를 해결하는 것이라고 말하고 싶습니다. 그렇게 하면 문제가 어떻게 작동하는지 이해할 수 있을 것입니다.

여기 제가 8비트 비부호 인트를 사용해서 한 일이 있습니다.

  1. 우리의 번호는 75입니다. 위치 6부터 시작하는 4비트를 원합니다. 함수에 대한 호출은 비트(75,6,4)를 얻을 것입니다.

  2. 이진법에서 75는 0100 1011입니다.

  3. 그래서 이렇게 가장 낮은 차수의 비트부터 시작해서 4비트 길이의 마스크를 만듭니다.

~0 = 1111 1111
<<4 = 1111 0000
~ = 0000 1111

좋아요, 마스크를 챙겼어요.

  1. 이제 숫자에서 원하는 비트를 가장 낮은 순서의 비트로 밀어 넣음으로써 이진수 75를 6+1-4=3으로 이동시킵니다.

0100 1011 >>3 0000 1001

이제 낮은 순서의 정확한 비트 수와 낮은 순서의 원래 숫자에서 원하는 비트 수에 대한 마스크가 있습니다.

  1. 그래서 우리와 그들
0000 1001
& 0000 1111============ 0000 1001

그래서 답은 십진법 9 입니다.

참고: 높은 차수의 니블은 마침 모두 0이므로 이 경우 마스킹이 중복되지만 처음 시작한 숫자의 값에 따라 달라질 수 있습니다.

~(~0 << n)다가 .n대부분의 오른쪽 비트가 켜졌습니다.

0
   0000000000000000
~0
   1111111111111111
~0 << 4
   1111111111110000
~(~0 << 4)
   0000000000001111

으로 처리하면 해당 할 수 있습니다.n작은 조각들

편집: 평생 사용해온 이 프로그래머의 계산기, 아날로그X PCalc를 지적하고 싶었습니다.

에서 ANSIC이~0 << n정의되지 않은 동작을 야기합니다.

.~0는 음수이고 좌 shifting 음수는 정의되지 않습니다.

참조: C11 6.5.7/4 (이전 버전은 텍스트가 유사함)

의 .E1 << E2이다.E1E2빈가 있는 이 아닌 치;는 0다. [...] E1E1 × 2E2 결과 유형으로 나타낼 수 있으며, 결과 값입니다. 그렇지 않으면 동작이 정의되지 않습니다.

에서 이 이며, 순진하게 K&R C 는 K&R 이며 했습니다, .1부호화된 숫자의 왼쪽 시프트를 수행할 때 왼쪽에서 비트가 떨어집니다(이 코드는 2의 보 표현에도 의존합니다). 그러나 다른 일부 시스템은 이러한 속성을 공유하지 않으므로 C 표준화 프로세스에서는 이 동작을 정의하지 않습니다.

따라서 이 예는 역사적 호기심으로서 흥미로울 뿐이며 1989년 이후(이전까지는 아니더라도) 어떤 실제 코드에도 사용되어서는 안 됩니다.

예제 사용: int x = 0xF994, p = 4, n = 3; int z = getbits(x, p, n);

그리고 이 일련의 작업에 집중합니다 ~(~0 << n)

원하는 비트 집합(10010011 등)에 대해 원하는 비트만을 끌어내는 "마스크"를 생성합니다.그래서 10010011이나 0x03, 저는 xxxxx011에 관심이 있습니다. 싶습니다.입니까? 00000111제 int다입니다. 바이트 기계의 경우 0부터 시작하여 워드 기계의 경우 0x0000 등의 작업을 수행하도록 하겠습니다. 64비트 기계는 64비트 또는 0x0000000000000000000000을 나타냅니다.

제 not(~0)하고 111111111111다를 .
n만큼 오른쪽으로 이동(<<)하여 11111000을 얻습니다.
돼' 00000111.

그래서 10010011 & 00000111 = 00000011
부울 연산이 어떻게 작동하는지 기억하십니까?

ANSI C ~0 >> n되지 않은 합니다를(를) 시킵니다.

// 왼쪽 이동이 문제를 일으킨다는 게시물은 잘못된 것입니다.

부호 없는 매력, l;

m = ~0 >> 4; 255를 생성하고 있으며 ~0과 같으나,

m = ~0; l = m >> 4; 다음과 같은 정확한 값 15를 생성하고 있습니다.

m = 255 >> 4;

에는 .~0 <<

언급URL : https://stackoverflow.com/questions/197614/need-help-understanding-getbits-method-in-chapter-2-of-kr-c

반응형