이전 글에 이어서
subtract함수부터 쓰겠습니다.
add함수와 비슷한 모양이라 주석만으로 쉽게 이해가 되실겁니다.
또한, add와 subtract 함수를 완벽하게 이해하셨다면
이전 글의 + 오버로딩 함수와
아래의 - 오버로딩 함수를 충분히 이해하실 수 있으실 겁니다.
이로써 두 BigInteger형의 + , - 연산을 만들었습니다.
+ , - 연산을 이용해 += , -= 연산도 만들었습니다.
subtract함수부터 쓰겠습니다.
void BigInteger::subtract (const BigInteger &Left, const BigInteger &Right) { // Left의 크기에서 Right의 크기만큼을 빼서 this에 저장하는 함수입니다. // 이 함수를 호출하는 함수에서 left의 크기가 항상 크도록 설정 // | Left | - | Right | // 가 성립한다는 전제하에 subtract함수는 작동합니다. // 초기에는 divideWithRemainder함수에서 // subtract함수를 this->subtract(*this, x)와 같이 호출하여 /* if (Left.len < Right.len) { add(Right, Left); return; } */ // 이 필요하였지만, divide..함수의 알고리즘을 다른 것으로 // 교체 하면서 subtract함수를 호출하지 않게되어 삭제하였습니다. // 빼는데 될 수있는 가장 긴 길이는 Left.len Reallocate(Left.len); blocktype blk_temp = 0; // 두 블럭의 차를 잠시 저장하기 위해 // 자리내림 처리용 // borrowIn : 이전 자리에서 자리내림 발생? // borrowOut : 현 자리에서 연산으로 자리내림 발생? bool borrowIn, borrowOut; index i; // 낮은 자리 만큼 루프를 돌며 뺄셈 연산 for(i = 0, borrowIn = false; i < Right.len; i++){ blk_temp = Left.blk[i] - Right.blk[i]; // 자리 내림이 발생하면 // blk_temp > Left.blk[i] // blk_temp > Right.blk[i] // 위 두개를 모두 만족한다. // 그래서 두 개중에 하나만 사용하여 비교해 주면된다. borrowOut = (blk_temp > Left.blk[i]); if (borrowIn) { // 전 자리에서 자리내림 발생했는가? // BorrowIn으로 인한 자리내림 발생 가능성 처리 borrowOut |= (blk_temp==0); blk_temp--; } blk[i] = blk_temp; borrowIn = borrowOut; } // blk[Right.len - 1]에서 자리내림 발생했는가? // 또한, 큰 가능성은 없지만 연쇄 자리내림이 가능하다 // ex) 1000 - 1과 같은 경우와 비슷한 맥락 for(; borrowIn && i < Left.len; i++){ borrowIn = (Left.blk[i] == 0); blk[i] = Left.blk[i] - 1; } // 나머지는 그대로 대입 for(; i < Left.len; i++) blk[i] = Left.blk[i]; // 연산 결과로 생기는 선두 0블럭들을 모두 제거 ZapLeadingZeros(); }
add함수와 비슷한 모양이라 주석만으로 쉽게 이해가 되실겁니다.
또한, add와 subtract 함수를 완벽하게 이해하셨다면
이전 글의 + 오버로딩 함수와
아래의 - 오버로딩 함수를 충분히 이해하실 수 있으실 겁니다.
const BigInteger BigInteger::operator -(const BigInteger &x) const { BigInteger temp; // 둘 중 하나가 0일 때 처리 if (x.sign == Zero) return *this; if (sign == Zero) { temp = x; return -temp; } // 두 수의 부호가 다르다면 크기는 더해지고 // 부호는 this를 따르면 됩니다. if (sign != x.sign) { temp.add(*this, x); temp.sign = sign; } // 두 수의 부호가 같을 때 else { CmpResult cmp; // this와 x의 '크기'비교 cmp = CompareTo(x); if ( cmp == Equal ) ; // 같다면 결과는 0 else if ( cmp == Greater ) { // this > x인 경우 temp.subtract(*this, x); temp.sign = sign; } else { // this < x인 경우 temp.subtract(x, *this); // this의 부호에 따라 결과값의 부호가 달라짐 // Zero가 나오는 경우는 위에서 처리했으므로 // Zero가 나올 수는 없다. temp.sign = (sign ==Positive) ? Negative : Positive; } } return temp; }
이로써 두 BigInteger형의 + , - 연산을 만들었습니다.
+ , - 연산을 이용해 += , -= 연산도 만들었습니다.
'프로젝트 > 큰수 클래스(Big Numerics)' 카테고리의 다른 글
[BigInteger - 14] 나눗셈(Part 1) (0) | 2011.07.08 |
---|---|
[BigInteger - 13] 곱셈 (0) | 2011.07.08 |
[BigInteger - 11] 덧셈 (0) | 2011.07.07 |
[BigInteger - 10] 쉬프트 연산(Part3) (0) | 2011.07.06 |
[BigInteger - 9] 쉬프트 연산(Part2) (0) | 2011.07.05 |