예제 #1
0
	bignum exponent(const bignum &base_value, const bignum &power, int precision)
	{
		if (base_value.getBase() != power.getBase())
			return exponent(base_value, power.getConverted(power.getBase()));

		bignum one(1);
		one.setBase(base_value.getBase());
		one.setPositive();

		if (power.isZero())
			return one;

		//if the power is negative, return 1/solution
		if (power.isNegative())
			return one / exponent(base_value, power.absolute());

		if (power.getDecimalCount() > 0)
		{
			if (power < 1)
			{
				bignum modified_power(power);
				modified_power.leftShift(power.getDecimalCount());
				bignum divisor(1);
				divisor.setBase(power.getBase());
				divisor.leftShift(power.getDecimalCount());

				bignum gcf(greatestCommonFactor(modified_power, divisor));
				modified_power /= gcf;
				divisor /= gcf;

				bignum divisor_root_of_base = jep::root(divisor, base_value, precision);
				return exponent(divisor_root_of_base, modified_power).getRoundedAllDigits(ONES_PLACE - precision);
			}

			else
			{
				bignum power_decimal = power % 1;
				bignum power_int = power.getRoundedDown(ONES_PLACE);

				return exponent(base_value, power_int, precision) * exponent(base_value, power_decimal, precision);
			}
		}

		bignum counter = power.absolute();
		bignum temp(base_value);

		//n^0 always returns 1
		if (power.isZero())
			return one;

		while (counter > one)
		{
			temp *= base_value;
			counter--;
		}

		return temp;
	}
예제 #2
0
	bignum multiplyNumbers(const bignum &bn1, const bignum &bn2)
	{
		if (bn1.getBase() != bn2.getBase())
			return multiplyNumbers(bn1, bn2.getConverted(bn1.getBase()));

		bignum temp(0);
		temp.setBase(bn1.getBase());

		if (bn1.isZero() || bn2.isZero())
			return temp;

		//multiply bn1 by each digit of bn2 independently, then add the values together
		int counter = bn2.getDigitRange();
		for (int i = 0; i < counter; i++)
		{
			int toMultiply = (ONES_PLACE - bn2.getDecimalCount()) + i;

			//verify function isn't checking beyond bounds of the stored array
			if (toMultiply >= 0)
			{
				if (toMultiply >= MAXDIGITS)
					throw error_handler(__FILE__, __LINE__, "The value being calculated is too large for the settings provided");

				bignum toAdd = multiplyNumbersSimple(bn1.absolute(), bn2.getDigit(toMultiply));

				toAdd.leftShift(i);
				temp += toAdd;
			}
		}

		if (bn1.isNegative() != bn2.isNegative())
			temp.setNegative();

		//adjust for added decimal places during multiplication
		temp.rightShift(bn2.getDecimalCount());

		temp.updateDigits();
		return temp;
	}
예제 #3
0
	bignum divideNumbers(const bignum &bn1, const bignum &bn2)
	{
		if (bn2.isZero())
			throw error_handler(__FILE__, __LINE__, "Cannot divide a number by zero");

		bignum temp;
		bool negative_result = (bn1.isNegative() != bn2.isNegative());

		if (bn1.getBase() != bn2.getBase())
			return divideNumbers(bn1, bn2.getConverted(bn1.getBase()));

		//set base of the return value to match that of the passed values
		int baseSet = bn1.getBase();
		temp.setBase(baseSet);

		bool remainder = false;
		bool end = false;
		int index = bn1.getDigitCount() - 1;

		//starting with the left-most digit, create a bignumber of that digit that matches the set base
		bignum number_to_compare(bn1.getDigit(index));
		number_to_compare.convertBase(baseSet);

		//ignore decimal places when comparing dividend to digits of the divisor
		bignum nextNumber = divideNumbersSimple(number_to_compare, bn2.absolute().noDecimal(), remainder);
		bignum number_to_subtract;
		number_to_subtract.setBase(baseSet);

		while (!end && index >= 0)
		{
			if (index >= MAXDIGITS)
				throw error_handler(__FILE__, __LINE__, "The value being calculated is too large for the settings provided");

			if (remainder == false && index < ONES_PLACE - bn1.getDecimalCount())
				end = true;

			temp.setDigit(index, nextNumber.getDigit(ONES_PLACE));
			index--;

			number_to_subtract = bn2.absolute().noDecimal() * nextNumber;
			number_to_subtract.updateDigits();
			number_to_compare -= number_to_subtract;
			number_to_compare.leftShift(1);

			if (index >= 0)
			{
				bignum digit(bn1.getDigit(index));
				digit.convertBaseSimple(number_to_compare.getBase());
				number_to_compare += digit;
			}

			nextNumber = divideNumbersSimple(number_to_compare, bn2.absolute().noDecimal(), remainder);

			if (index < 0)
				end = true;
		}

		if (negative_result && temp != 0)
			temp.setNegative();

		temp.leftShift(bn2.getDecimalCount());
		return temp;
	}