2014-12-27 6 views
2

나는 KnR을 팔로우하고있다. 이것은 연습 2-8입니다. 그것은 숫자를 몇 비트만큼 오른쪽으로 회전시키는 함수를 만드는 것이라고 말합니다.기타 번호 2-8 : 숫자를 오른쪽으로 회전하십시오. 이거 괜찮아?

대답은 '할 것 같다'라는 생각이 떠오르며 두 줄로 나왔습니다. 그러나, 나는 다른 방법을 온라인으로 확인하고 있었다. This SO answer은 각 비트를 하나씩 이동하는 것에 대해 이야기합니다. 내가 (아래 코드 에서처럼) 대량으로 이동하면 무엇이 잘못됩니까? 내가 놓친 게 있니?

#include <stdio.h> 

/* Rotate number 'num' to the right by 'rbits' bits */ 

int RotRight(unsigned int num,int rbits){ 

    unsigned int mask = num << ((sizeof(int)*8)-rbits); 
    return (num>>rbits)|mask; 
} 

편집 : 의견에서 배운 내용을 수용하기 위해 위의 코드를 수정 한 버전이 있습니다. 이게 좋아 보이니?

#include <stdio.h> 
#include <stdlib.h> 
#include <limits.h> 

int RotRight(int num,int rbits){ 

    if(num<0) { 
     fprintf(stderr,"Rotating negative numbers is undefined\n"); 
     exit(EXIT_FAILURE); 
    } 

    if(rbits >= sizeof(int)*CHAR_BIT) rbits = rbits % (sizeof(int)*CHAR_BIT); 
    if(rbits<=0) return num; // rbit range should be 0 to (bitwidth - 1) 


    unsigned int mask = num << ((sizeof(int)*CHAR_BIT)-rbits); 
    return (num>>rbits)|mask; 
} 
+1

이 함수가 전달 된 num과 다른 유형을 반환하는 이유가 궁금합니다. –

+0

부호있는 비트를 이동하기가 까다 롭기 때문에 (그리고 아마도 내가해야 할 일이 아닐 수도 있습니다). 그래서 입력을 부호없는 것으로 유지했습니다. 그래도 출력 형식을 unsigned로 유지하는 것에 대해 생각하지 않았습니다! – Somjit

+0

또한 논리적 인 변화를 생각하고 있었으며 산술적 인 것이 아닙니다. – Somjit

답변

1

코드의 첫 번째 버전은 좋았지 만 두 번째 버전은 지나치게 복잡해졌습니다. 단순화하기 위해 부호없는 숫자를 사용하도록 제안하십시오.

코드가 비트를 회전시키기 때문에, N 배의 비트 폭을 회전하는 것은 0을 회전하는 것과 같습니다. IOW, 시프트 수의 최하위 비트만 사용하면됩니다.

#include <stdio.h> 
#include <limits.h> 

/* Rotate number 'num' to the right by 'rbits' bits */ 

unsigned RotRight(unsigned num, unsigned rbits) { 
    #define BIT_WIDTH (CHAR_BIT * sizeof num) 
    #define RBIT_MASK (BIT_WIDTH - 1) 
    rbits %= BIT_WIDTH; // compiler likely to change this to rbits &= RBIT_MASK; 
    unsigned mask = num << ((BIT_WIDTH - rbits) % BIT_WIDTH); 
    return (num >> rbits) | mask; 
} 
+0

왜 '//이 컴파일러가 rbits & RBIT_MASK; ? – Somjit

+1

@Somjit'BIT_WIDTH'는 상수입니다. 그것은 2의 거듭 제곱 가능성이 높습니다. 이 경우'rbits % = BIT_WIDTH'는'rbits & = RBIT_MASK'와 같고'& ='는 빠른 명령어입니다 - 아마도'% ='보다 빠릅니다. – chux