InfInt InfInt::pow(const InfInt& exp) { //exp is positive number InfInt temp(*this); if( exp.digits.compare("0") < 0 ) { return InfInt(); } InfInt result("1"); result.thesign = true; for ( int i = 0 ; i < exp ; i++ ) { result = temp * result; } if ( temp.thesign == false && (((exp.digits.at(0) - '0') % 2)==1)) { result.thesign = false; } return result; }
InfInt operator+(const InfInt& self, const InfInt& other) { int carry = 0; InfInt ret; ret.digits.clear(); int maxLength = self.digits.size() > other.digits.size() ? self.digits.size() : other.digits.size(); if ( self.thesign == other.thesign ) { if ( self.thesign == true ) { // +, + for ( int i = 0; i < maxLength || carry == 1; i++ ) { int result = 0; if ( (int)self.digits.size() > i ) { result += (self.digits.at(i) - ASCII_POSITION); } if ( (int)other.digits.size() > i ) { result += + (other.digits.at(i) - ASCII_POSITION); } result += carry; if ( result >= 10 ) { result -= 10; carry = 1; } else { carry = 0; } ret.digits += result + 48; } } else { // -, - for ( int i = 0; i < maxLength || carry == 1; i++ ) { int result = 0; if ( (int)self.digits.size() > i ) { result += (self.digits.at(i) - ASCII_POSITION); } if ( (int)other.digits.size() > i ) { result += + (other.digits.at(i) - ASCII_POSITION); } result += carry; if ( result >= 10 ) { result -= 10; carry = 1; } else { carry = 0; } ret.digits += result + ASCII_POSITION; } ret.thesign = false; } } else { // self.thesign != other.thesign // if ( self.thesign == true ) { // +, - if ( self.digits.size() > other.digits.size() ) { // 길이가 self가 더 클 경우 -> self에서 빼기 selfIsBigger: for ( int i = 0; i < maxLength; i++ ) { int result = 0; if ( (int)self.digits.size() > i ) { result += (self.digits.at(i) - ASCII_POSITION) - carry; } if ( (int)other.digits.size() > i ) { result -= (other.digits.at(i) - ASCII_POSITION); } if ( result < 0 ) { result = 10 + result; carry = 1; } else { carry = 0; } ret.digits += result + ASCII_POSITION; } for ( int i = ret.digits.size() - 1; i >= 0; i-- ) { if ( ret.digits.at(i) == '0' ) { ret.digits.erase(ret.digits.size()-1); //ret.digits.pop_back(); } else { break; } } ret.thesign = self.thesign; if ( ret.digits.compare("0") == 0 ) { ret.thesign = true; } } else if ( self.digits.size() < other.digits.size() ) { // 길이가 self가 더 작을 경우 -> other에서 빼기 selfIsSmaller: for ( int i = 0; i < maxLength; i++ ) { int result = 0; if ( (int)other.digits.size() > i ) { result += (other.digits.at(i) - ASCII_POSITION) - carry; } if ( (int)self.digits.size() > i ) { result -= (self.digits.at(i) - ASCII_POSITION); } if ( result < 0 ) { result = 10 + result; carry = 1; } else { carry = 0; } ret.digits += result + ASCII_POSITION; } for ( int i = ret.digits.size() - 1; i >= 0; i-- ) { if ( ret.digits.at(i) == '0' ) { ret.digits.erase(ret.digits.size()-1); //ret.digits.pop_back(); } else { break; } } ret.thesign = other.thesign; if ( ret.digits.compare("0") == 0 ) { ret.thesign = true; } } else { // 길이가 같을 경우 for ( int i = self.digits.size() - 1; i >= 0; i-- ) { if ( self.digits.at(i) - other.digits.at(i) > 0 ) { goto selfIsBigger; } else if ( self.digits.at(i) - other.digits.at(i) < 0 ) { goto selfIsSmaller; } /* else { return InfInt("0"); } */ } return InfInt("0"); } /* } else { // -, + } */ } return ret; }
void testInfInteger() { InfInt myint1 = "15432154865413186646848435184100510168404641560358"; InfInt myint2 = 156341300544608LL; //std::cout << "SIZES: " << myint1.size() << " " << myint2.size() << std::endl; { assert(InfInt(INT_MIN) == INT_MIN); assert(InfInt(INT_MAX) == INT_MAX); assert(InfInt(INT_MIN).toInt() == INT_MIN); assert(InfInt(INT_MAX).toInt() == INT_MAX); assert(InfInt(LONG_MIN) == LONG_MIN); assert(InfInt(LONG_MAX) == LONG_MAX); assert(InfInt(LONG_MIN).toLong() == LONG_MIN); assert(InfInt(LONG_MAX).toLong() == LONG_MAX); assert(InfInt(LONG_LONG_MIN) == LONG_LONG_MIN); assert(InfInt(LONG_LONG_MAX) == LONG_LONG_MAX); assert(InfInt(LONG_LONG_MIN).toLongLong() == LONG_LONG_MIN); assert(InfInt(LONG_LONG_MAX).toLongLong() == LONG_LONG_MAX); assert(InfInt(0U) == 0U); assert(InfInt(UINT_MAX) == UINT_MAX); assert(InfInt(0U).toUnsignedInt() == 0U); assert(InfInt(UINT_MAX).toUnsignedInt() == UINT_MAX); assert(InfInt(0UL) == 0UL); assert(InfInt(ULONG_MAX) == ULONG_MAX); assert(InfInt(0UL).toUnsignedLong() == 0UL); assert(InfInt(ULONG_MAX).toUnsignedLong() == ULONG_MAX); assert(InfInt(0ULL) == 0ULL); assert(InfInt(ULONG_LONG_MAX) == ULONG_LONG_MAX); assert(InfInt(0ULL).toUnsignedLongLong() == 0ULL); assert(InfInt(ULONG_LONG_MAX).toUnsignedLongLong() == ULONG_LONG_MAX); } for (int i = 0; i < 5000; ++i) { InfInt i1, i2; { i1 = myint1++; assert(i1-- == myint1-1); assert(myint1-3 == --i1); assert(i1 == myint1-3); } { i2 = myint2--; assert(i2++ == myint2+1); assert(myint2+3 == ++i2); assert(i2 == myint2+3); } { assert(InfInt(155)/InfInt(-37) == 155/(-37)); assert(InfInt(155)%InfInt(-37) == 155%(-37)); assert(InfInt(-155)/InfInt(-37) == (-155)/(-37)); assert(InfInt(-155)%InfInt(-37) == (-155)%(-37)); assert(InfInt(-155)/InfInt(37) == (-155)/37); assert(InfInt(-155)%InfInt(37) == (-155)%37); } { InfInt root = myint1.intSqrt(); InfInt rootPlusOne = root + 1; assert(root*root <= myint1 && myint1 <= rootPlusOne*rootPlusOne); assert((myint1*myint1).intSqrt() == myint1); assert((myint1/myint2) * myint2 + (myint1%myint2) == myint1); } { i1 = myint1; i1 += myint2; assert(i1 == myint1 + myint2); } { i1 = myint1; i1 -= myint2; assert(i1 == myint1 - myint2); } { i1 = myint1; i1 /= myint2; assert(i1 == myint1 / myint2); } { i1 = myint1; i1 *= myint2; assert(i1 == myint1 * myint2); } { i1 = myint1; i1 %= myint2; assert(i1 == myint1 % myint2); } } assert(InfInt(1).intSqrt() == 1); assert(InfInt(2).intSqrt() == 1); assert(InfInt(3).intSqrt() == 1); assert(InfInt(4).intSqrt() == 2); assert(InfInt(5).intSqrt() == 2); assert(InfInt(6).intSqrt() == 2); assert(InfInt(7).intSqrt() == 2); assert(InfInt(8).intSqrt() == 2); assert(InfInt(9).intSqrt() == 3); }