이전 글에 이어서
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형의 + , - 연산을 만들었습니다.
+ , - 연산을 이용해 += , -= 연산도 만들었습니다. 
Posted by 투명테잎