본문 바로가기

Programming/General

shift 연산자(>>)를 이용한 곱셈과 나눗셈

linux kernel code 를 분석하다 보면 가끔 복잡한 shift 연산자 들이 나옵니다.

shift 연산자들은 연산의 속도가 빨라서 고수 개발자들에게 사랑받곤 하지만 

분석하는 입장에서는 그 의미가 모호해서 답답할 때가 많습니다.

그중 자주 사용되는 shift 연산자를 이용한 나눗셈을 알아 봅시다.



totalpages  = mtd->size >> mtd->writesize_shift;

이 구문의 이미는 무었일까요?

보통 mtd 는 수많은 page 들로 이루어져 있습니다. page 는 write단위이기도 해서 writesize 와 동일합니다.

writesize = 4096 = (2진수)1000000000000

이렇게 됩니다.

shift 연산자는 1 을 얼마나 밀었냐 인데요. 위에서 0 의 갯수를 세면 되겠지요?

writesize_shift = 12

입니다.

결국 연산을 해석하면 아래와 같습니다.

mtd size >> writesize_shift  == mtd size / writesize

반대는 곱하기가 되어 버리지요.

간단한 예제 프로그램을 첨부해 봅니다.

#include <iostream>
using namespace std;

void main()
{
 unsigned long shift = 2; // (2진수)100 = (10진수)4
 unsigned long addr = 1;
 int i=0;

 while(i++<10)
 {
  cout << hex << "0x" << addr << " - " << dec << addr << endl;
  addr = addr << shift;
 }
}


결과

0x1 - 1
0x4 - 4
0x10 - 16
0x40 - 64
0x100 - 256
0x400 - 1024
0x1000 - 4096
0x4000 - 16384
0x10000 - 65536
0x40000 - 262144
Press any key to continue



수학적인 증명은 생략하겠지만 이정도는 알아두어야 소스 분석에 어려움이 없을 것입니다.