본문 바로가기
IT/C Language

산술 연산 관련 팁

by Jang HyunWoong 2014. 12. 19.

unsigned 는 쓸 수 있다면 무조건 써라

 

예를 들면 사람의 인원수, 책들의 개수 같이 도저히 음수가 될 수 없는 데이터를 보관하는 변수에는 unsigned 키워드를 붙이는 것이 좋습니다. 

 

왜냐하면 많은 수의 CPU 에서는 unsigned 값들을 더 빨리 처리하도록 되어 있기 때문입니다.

 

나눗셈을 피해라 (1) 

아래는 초 를 증가시켜주는 함수 입니다. 

int inc_second(int second) 

    return (++second)%60; 


여기서 문제는 나눗셈은 매우매우 느린 연산이라는 것입니다. 

다른 덧셈 뺄셈에 비해 몇 배 가까이 느리기 때문에 엄청난 시간 손해가 있겠지요. 


우리가 만약 second 가 60 보다 커질 일이 없다는 것을 알고 있다면 굳이 60 으로 나눌 필요 없이 if 문으로 60 일 때만 0 을 리턴해주면 되는 것입니다. 


왜냐하면 if 문은 나눗셈 보다는 훨씬 빠르게 처리가 되기 때문이지요. 

int inc_second(int second) 

    ++second; 
    if(second >= 60) 
        return 0; 
    return second; 
}



따라서 위와 같이 하면 훨씬 시간을 아낄 수 있습니다. 


나눗셈을 피해라 (2) 

앞에서도 말했듯이 나눗셈은 시간이 매우매우 오래 걸리는 작업이라고 했습니다. 

그런데 놀랍게도 2 의 멱수들 (2,4,8,16,32 ...)  로 나눌 때에는 굳이 나눗셈을 사용하지 않고도 매우 간단하게 처리할 수 있는 방법이 있습니다. 바로 '쉬프트' 연산을 사용하는 것입니다. 


쉬프트는 컴퓨터 연산 중에서도 가장 빠른 연산이므로 이를 잘만 활용한다면 시간을 엄청나게 절약할 수 있습니다. 

2 의 멱수들을 이진수로 표현해 보면 1, 10, 100, 1000 등이 될 것입니다. 그럼 감이 오시나요? 


우리가 만일 10 진수로 생각할 때 7865 를 100 으로 나누면 몫이 얼마가 될까요? 

우리는 별로 고민하지 않고도 78 이라고 말할 수 있을 것입니다. 


왜냐하면 단순히 끝의 두 자리를 버려버리면 되기 때문이지요. 이진수도 마찬가지 입니다. 11101010 을 1000 으로 나눈 몫은 얼마일까요? 이는 단순히 마지막 세자리를 버리면 되므로 11101 이 되겠지요. 

  이 아이디어를 이용하면 1000 (이진수) 으로 나눌 때 에는 수를 오른쪽으로 3 칸 쉬프트 해버리면 됩니다.  32 는 2 의 5 승이므로 오른쪽으로 5 칸 쉬프트 해버리면 됩니다. 

 

 

 

#include <stdio.h> 
int main() 

    int i; 
    printf("정수를 입력하세요 : "); 
    scanf("%d", &i); 

    printf("%d 를 32 로 나누면 : %d \n", i, i/32); 
    printf("%d 를 5 칸 쉬프트 하면 : %d \n", i, i >> 5); 

    return 0; 
}

 

비트 연산 활용하기

비트 연산을 가장 많이 활용하는 예로 또한 홀수/짝수 판별이 있습니다. 여태까지 여러분들은 아마 홀수 짝수 판별을 

 

    if(i % 2 == 1) // 이 수가 홀수인가 
    { 
        printf("%d 는 홀수 입니다 \n", i); 
    } 
    else 
    { 
        printf("%d 는 짝수 입니다 \n", i); 
    }


와 같이 만드셨을 것입니다. 그런데 제가 앞에서 계속 강조해 왔던 것이지만, 나눗셈 연산은 매우 느립니다! 하지만 놀랍게도 단순한 AND 연산 한번으로 이를 해결할 수 있습니다. 

    if(i & 1) // 이 수가 홀수인가 
    { 
        printf("%d 는 홀수 입니다 \n", i); 
    } 
    else 
    { 
        printf("%d 는 짝수 입니다 \n", i); 
    }


  만일 어떤 정수가 홀수라면, 2 진수로 나타냈을 때 맨 마지막 자리가 1 이여야 합니다 (당연하지요?) 이를 이용해서 단순히 어떤 정수의 맨 마지막 비트가 1 인지만 확인하면 되지요? 

 

근데 위에서 강조했듯 것을 보면 맨 마지막 비트가 1 인지 확인하려면 맨 마지막 비트만 1 인 수(즉 1) 과 AND 하면 됩니다. 아래 소스로 컴파일해서 실행해보면 잘 됨을 알 수 있습니다. 

 

#include <stdio.h> 
int main() 

    int i; 
    scanf("%d", &i); 

    if(i & 1) // 이 수가 홀수인가 
    { 
        printf("%d 는 홀수 입니다 \n", i); 
    } 
    else 
    { 
        printf("%d 는 짝수 입니다 \n", i); 
    } 
    return 0; 
}

출처 - http://itguru.tistory.com/129

반응형

'IT > C Language' 카테고리의 다른 글

파스칼의 세모꼴  (0) 2014.12.19
uchar  (0) 2014.12.19
[클래스] 접근 지정자  (0) 2014.12.19
클래스  (0) 2014.12.19
긴 이름을 짧게 만들어 주는 typedef  (0) 2014.12.19