본격적으로 쉬프트 연산을 만들어 보겠습니다.
숫자들은 blk라는 unsigned long형 배열에 저장되있습니다.

하.. 배열의 시작번지를 인수로 주면 배열 전체를 n비트 쉬프트 시켜주는 함수가


blocktype *blk;
blk = blk << n;


있었으면 아주 편했을텐데 말인데.. 그런건 없더라구요.. 
결국, blk의 블럭 하나하나를 쉬프트 해야만 했습니다.
(..
memmove함수를 생각해봤지만 이동단위가 byte여서
bit를 쉬프트 해야 하는 이번 경우에는 적용시킬 수 없었습니다.)

우선 몇 블럭, 몇 비트를 쉬프트 해야 하는지 구합니다.
만약 blk를 40비트 왼쪽으로 쉬프트 한다면
(blocktype은 32비트이므로, 한 블록은 32비트입니다.)
32 + 8이므로
1블럭 + 8비트 쉬프트입니다.

이제, Get_LShiftedBlock함수를 호출하여
젤 낮은 자리부터 8비트 쉬프트 한것을 1블럭 옆에 대입합니다.

일반화 시킨다면
x크기의 blk를
(blk[0],blk[1], blk[2]...blk[x-2]...blk[x-1])
n비트 쉬프트시
blk[i]블럭을
n%32만큼 쉬프트 시켜서
blk[n/32 + i]블럭에 대입합니다.
이것을 i가 0부터 x-1까지, x번 반복하는 것이지요. 

이해가 되셨나요?
그럼 이제 코드를 보겠습니다.
 

const BigInteger BigInteger::operator <<(const int leftmove) const
{
	// (*this) * 2^(leftmove)를 연산
	BigInteger temp; // 결과값 리턴용
	/*
	 * 특수 경우를 제외합니다.
	 * 1. *this가 0이면, 0 리턴
	 * 2. leftmove가 0이면, *this 리턴
	 * 3. leftmove가 음수면, >> 쉬프트로 연산
	 */
	if (sign == Zero)
		return temp;
	if (leftmove == 0)
		return *this;
	else if (leftmove < 0)
		return *this >> (-leftmove);
	length shiftblocks = leftmove / N;
	length shiftbits = leftmove % N;

	// +1은 shitfbits때문에 생기는 추가되는 블록 저장용
	temp.Reallocate(len + shiftblocks + 1);

	// 한블럭씩 shiftbits만큼 쉬프트 시켜 대입해줍니다.
	index i, j;
	for (i = 0, j = shiftblocks; i <= len; i++, j++)
		temp.blk[j] = Get_LShiftedBlock(i, shiftbits);

	// Get_LShiftedBlock(len - 1, shiftbits)가 0일 경우...
	if (temp.blk[temp.len - 1] == 0)
		temp.len--;
	temp.sign = sign;
	return temp;
}


위에서 설명하여서 비교적 이해가 되시리라 생각됩니다.
그런데
temp를 재할당 하는 함수에서 +1을 하였습니다.
왜 그랬을까요?
shiftbits가 0이면 그냥 shiftblocks만큼 배열의 원소들을 옮겨주면 됩니다.
하지만 shiftbits가 0이 아니라면 배열의 최고차항도 shiftbits만큼 쉬프트 해주어 합니다.

그런데 만약 배열의 최고차항 배열의 원소가
다음을 만족한다면..

(  blk[len - 1] >> ( 32 - shiftbits)  ) != 0

배열의 길이가 len + shiftblocks보다 1칸 더 많아져야 합니다.
(  blk[len - 1] >> ( 32 - shiftbits)  ) 이것을 저장한 1블럭이 필요하기 때문입니다.
무슨 소린야?? 라고 하실지도 모르겠습니다.
근데.. 곰곰히 생각해보시면.. 아 그렇구나 하실겁니다.

블럭을 쉬프트 대입 후,
temp.blk[temp.len - 1] 가 0인지 비교합니다.
이건 다음과 뜻이 같습니다.
==  this->Get_LShiftedBlock(len - 1, shiftbits)가 0인가?
==  (  *this.blk[len - 1] >> ( 32 - shiftbits)  )가 0인가?
0이라면 temp.len을 한칸 줄입니다.
그 후, 부호를 대입하면 끝입니다..!!

글이 많이 길어졌네요..
다음글에서 >>연산에 대해 쓰겠습니다. 
Posted by 투명테잎