Esempio n. 1
0
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;
}
Esempio n. 2
0
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;
}
Esempio n. 3
0
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);
}