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; }
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; }
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; }