unsigned 는 쓸 수 있다면 무조건 써라
예를 들면 사람의 인원수, 책들의 개수 같이 도저히 음수가 될 수 없는 데이터를 보관하는 변수에는 unsigned 키워드를 붙이는 것이 좋습니다.
왜냐하면 많은 수의 CPU 에서는 unsigned 값들을 더 빨리 처리하도록 되어 있기 때문입니다.
나눗셈을 피해라 (1)
아래는 초 를 증가시켜주는 함수 입니다.
{
return (++second)%60;
}
여기서 문제는 나눗셈은 매우매우 느린 연산이라는 것입니다.
다른 덧셈 뺄셈에 비해 몇 배 가까이 느리기 때문에 엄청난 시간 손해가 있겠지요.
우리가 만약 second 가 60 보다 커질 일이 없다는 것을 알고 있다면 굳이 60 으로 나눌 필요 없이 if 문으로 60 일 때만 0 을 리턴해주면 되는 것입니다.
왜냐하면 if 문은 나눗셈 보다는 훨씬 빠르게 처리가 되기 때문이지요.
{
++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 칸 쉬프트 해버리면 됩니다.
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;
}
비트 연산 활용하기
비트 연산을 가장 많이 활용하는 예로 또한 홀수/짝수 판별이 있습니다. 여태까지 여러분들은 아마 홀수 짝수 판별을
{
printf("%d 는 홀수 입니다 \n", i);
}
else
{
printf("%d 는 짝수 입니다 \n", i);
}
와 같이 만드셨을 것입니다. 그런데 제가 앞에서 계속 강조해 왔던 것이지만, 나눗셈 연산은 매우 느립니다! 하지만 놀랍게도 단순한 AND 연산 한번으로 이를 해결할 수 있습니다.
{
printf("%d 는 홀수 입니다 \n", i);
}
else
{
printf("%d 는 짝수 입니다 \n", i);
}
만일 어떤 정수가 홀수라면, 2 진수로 나타냈을 때 맨 마지막 자리가 1 이여야 합니다 (당연하지요?) 이를 이용해서 단순히 어떤 정수의 맨 마지막 비트가 1 인지만 확인하면 되지요?
근데 위에서 강조했듯 것을 보면 맨 마지막 비트가 1 인지 확인하려면 맨 마지막 비트만 1 인 수(즉 1) 과 AND 하면 됩니다. 아래 소스로 컴파일해서 실행해보면 잘 됨을 알 수 있습니다.
int main()
{
int i;
scanf("%d", &i);
if(i & 1) // 이 수가 홀수인가
{
printf("%d 는 홀수 입니다 \n", i);
}
else
{
printf("%d 는 짝수 입니다 \n", i);
}
return 0;
}
'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 |