다음으로 쉬프트 연산입니다.
하.. ^^
쉬프트 연산도 만들 때 고생 많이 했습니다.
배열을 쉬프트하는 연산을 기본적으로 제공하지 않으므로
배열 쉬프트 연산을 만들어 직접 blk 배열을 쉬프트 하는 수밖에 없습니다.
그러기 위해 보조 함수를 만들었습니다.
다음이 그 보조 함수입니다.
const BigInteger::blocktype BigInteger::Get_LShiftedBlock(const index x, const length n) const { // x는 0~len까지의 범위를 가집니다. // n은 0~31까지의 범위를 가집니다. // x의 전 블록 상위 n비트를 추출 합니다. blocktype lowblk = (x == 0 || n == 0) ? 0 : ( blk[x - 1] >> (N - n) ); // x 블록을 왼쪽으로 n번 쉬프트한 것을 추출 합니다. blocktype highblk = (x == len) ? 0 :( blk[x] << n ); // 위 두 블럭의 합집합을 리턴합니다. return lowblk | highblk; }blk배열을 블록단위로 쉬프트 하는 함수입니다.
x는 blk의 몇 번째를 쉬프트 할지 결정하고,
n은 몇 비트를 쉬프트 할지 결정합니다.
즉, 다음과 같이 사용하면
Get_LShiftedBlock(3,4);
blk[3] << 4 한 것과 blk[2]의 상위 4비트와의 합집합을 구한다는 것입니다.
blk[x]를 왼쪽으로 2 쉬프트 한다면
blk[x]의 하위 2비트는 0으로 채워지게 됩니다.
하지만 BigInteger형에서는 0으로 채워져서는 안되며
아래 배열요소의 상위 2비트값으로 채워져야하합니다.
그래야 배열에서 연속적으로 저장한 숫자들의 쉬프트를 구현했다고
말할 수 있습니다.
자, 그럼 문제입니다.. !!!
왜 오른쪽으로 쉬프트 하는 함수는 없을까요?
위 함수를 쓰면 되기 때문입니다.
blk3]을 오른쪽으로 4비트 쉬프트 시키려면 어떻게 함수를 호출해야 할까요??
Get_LShiftedBlock(4,28);
을 호출하면 됩니다.
즉, x블록을 오른쪽으로 n비트 쉬프트 시키려면
Get_LShiftedBlock(x + 1, 32 - n);
을 호출해주면 됩니다.
엥?? 무슨 소리냐구요??
곰곰히 생각해보세요.. ^^
안되는 머리로 생각 하려니 전 오래 걸렸습니다.. ㅠㅠ
이제 저 보조함수를 이용해서
왼쪽, 오른쪽으로 쉬프트 하는 쉬프트연산자를 오버로딩 해보겠습니다.
그 전에!!
또, 정의를 새롭게 해야합니다.
정수형에서 쉬프트 연산자는
왼쪽 혹은 오른쪽으로 모든 n비트를 옮긴 후, 범위 밖은 버리고, 공백은 0으로 채우는 것으로 정의되있습니다.
그러나, BigInteger형은 비트수가 정해진게 아니라서 위의 정의가 성립하지 않습니다.
그래서 이것도 연산의 특징을 정의로 간주하고 만들었습니다.
즉, << 쉬프트 연산은 모든 비트를 왼쪽으로 옮기데, 블록이 부족하면 새롭게 할당합니다.
그러므로, a << b를 호출하면 무조건 a * 2^b 가 성립하게 됩니다.
>> 쉬프트는 정수형과 비슷합니다.
모든 비트를 오른쪽으로 옮기데, 블록이 남으면 없앱니다.
따라서, a >> b를 호출하면 무조건 a * 2^(-b)가 성립합니다.
또한, 기본 쉬프트 연산과는 다른점이 있습니다.
기본 쉬프트는
b가 0 <= b < sizeof(a) 안에서만 정상적으로 작동합니다.
하지만, BigInteger형이 쉬프트 연산은 모든 int범위 내에서 성립하게 만들었습니다.
1. b가 0이면 a리턴
2. b가 양수이면 정상적으로 실행 -> a * 2^b
3. b가 음수라면 반대쉬프트 실행 -> a * 2^b, (b<0)
예로 1 << - 1은 1 >> 1과 같다는 말입니다.
휴... 기네요.. ㅋ
다음 글에서 계속 이어 가겠습니다. ^^
'프로젝트 > 큰수 클래스(Big Numerics)' 카테고리의 다른 글
[BigInteger - 10] 쉬프트 연산(Part3) (0) | 2011.07.06 |
---|---|
[BigInteger - 9] 쉬프트 연산(Part2) (0) | 2011.07.05 |
[BigInteger - 7] 비트연산 (0) | 2011.07.01 |
[BigInteger - 6] 비교연산 (1) | 2011.06.30 |
[BigInteger - 5] 기본형으로부터의 생성 / 변환 (1) | 2011.06.29 |