bool greaterThan(const bignum &bn1, const bignum &bn2) { //if bases are different, convert the second and re-evaluate if (bn1.getBase() != bn2.getBase()) return greaterThan(bn1, bn2.getConverted(bn1.getBase())); if (bn1 == bn2) return false; if (bn1.isNegative() && !bn2.isNegative()) return false; if (!bn1.isNegative() && bn2.isNegative()) return true; if (bn1.isNegative() && bn2.isNegative()) return (lessThan(bn1.absolute(), bn2.absolute())); if (bn1.getDigitCount() > bn2.getDigitCount()) return true; if (bn1.getDigitCount() < bn2.getDigitCount()) return false; for (int i = bn1.getDigitCount() - 1; i >= 0; i--) { if (bn1.getDigit(i) > bn2.getDigit(i)) return true; if (bn1.getDigit(i) < bn2.getDigit(i)) return false; } return false; }
bool lessThan(const bignum &bn1, const bignum &bn2) { if (bn1.getBase() != bn2.getBase()) return lessThan(bn1, bn2.getConverted(bn1.getBase())); if (bn1 == bn2) return false; if (bn1.isNegative() && !bn2.isNegative()) return true; if (!bn1.isNegative() && bn2.isNegative()) return false; if (bn1.isNegative() && bn2.isNegative()) return (greaterThan(bn1.absolute(), bn2.absolute())); if (bn1.getDigitCount() < bn2.getDigitCount()) return true; if (bn1.getDigitCount() > bn2.getDigitCount()) return false; for (int i = bn1.getDigitCount() - 1; i >= 0; i--) { if (bn1.getDigit(i) < bn2.getDigit(i)) return true; if (bn1.getDigit(i) > bn2.getDigit(i)) return false; } return false; }
bool equals(const bignum &bn1, const bignum &bn2) { if (bn1.getBase() != bn2.getBase()) return equals(bn1, bn2.getConverted(bn1.getBase())); if (bn1.isNegative() != bn2.isNegative()) return false; if (bn1.getDigitCount() != bn2.getDigitCount()) return false; if (bn1.getDecimalCount() != bn2.getDecimalCount()) return false; for (int i = bn1.getDigitCount(); i > 0; i--) { if (bn1.getDigit(i - 1) != bn2.getDigit(i - 1)) return false; } return true; }
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; }
bignum subtractNumbers(const bignum &bn1, const bignum &bn2) { if (bn1.getBase() != bn2.getBase()) return subtractNumbers(bn1, bn2.getConverted(bn1.getBase())); int base = bn1.getBase(); bignum difference; difference.setBase(base); //evaluate the numbers being of equal absolute value if (bn1.absolute() == bn2.absolute()) { // -12 - 12 ---> -(12 + 12) if (bn1.isNegative() && !bn2.isNegative()) { bignum temp = addNumbers(bn1.absolute(), bn2.absolute()); temp.setNegative(); temp.updateDigits(); return temp; } // 12 - -12 ---> 12 + 12 if (!bn1.isNegative() && bn2.isNegative()) return addNumbers(bn1.absolute(), bn2.absolute()); // -12 - -12 ---> 0 if (bn1.isNegative() && bn2.isNegative()) { bignum temp; temp.setBase(base); return temp; } } //evaluate the numbers if absolute first is larger than absolute second if (bn1.absolute() > bn2.absolute()) { // -12 - 8 ---> -(12 + 8) if (bn1.isNegative() && !bn2.isNegative()) { bignum temp = addNumbers(bn1.absolute(), bn2.absolute()); temp.setNegative(); temp.updateDigits(); return temp; } // 12 - -8 ---> 12 + 8 if (!bn1.isNegative()&& bn2.isNegative()) return addNumbers(bn1.absolute(), bn2.absolute()); // -12 - -8 ---> -(12 - 8) if (bn1.isNegative() && bn2.isNegative()) { bignum temp = subtractNumbers(bn1.absolute(), bn2.absolute()); temp.setNegative(); temp.updateDigits(); return temp; } } //evaluate the numbers if absolute first is smaller than absolute second if (bn1.absolute() < bn2.absolute()) { // 8 - 12 ---> -(12 - 8) if (!bn1.isNegative()&& !bn2.isNegative()) { bignum temp = subtractNumbers(bn2.absolute(), bn1.absolute()); temp.setNegative(); temp.updateDigits(); return temp; } // -8 - 12 ---> -(8 + 12) if (bn1.isNegative() && !bn2.isNegative()) { bignum temp = addNumbers(bn1.absolute(), bn2.absolute()); temp.setNegative(); temp.updateDigits(); return temp; } // 8 - -12 ---> 8 + 12 if (!bn1.isNegative() && bn2.isNegative()) return addNumbers(bn1.absolute(), bn2.absolute()); // -8 - -12 ---> (12 - 8) if (bn1.isNegative() && bn2.isNegative()) return subtractNumbers(bn2.absolute(), bn1.absolute()); } int carry = 0; int digits = 0; int decimal = 0; //bool carry_negative = false; //sets decimal and digit values to the highest of each number decimal = (bn1.getDecimalCount() > bn2.getDecimalCount() ? bn1.getDecimalCount() : bn2.getDecimalCount()); digits = (bn1.getDigitCount() > bn2.getDigitCount() ? bn1.getDigitCount() + 1 : bn2.getDigitCount() + 1); for (int i = (ONES_PLACE - decimal); i < digits + 1 && i >= 0; i++) { if (i >= MAXDIGITS) throw error_handler(__FILE__, __LINE__, "The value being calculated is too large for the settings provided"); int tempNumber = bn1.getDigit(i) - bn2.getDigit(i); tempNumber -= carry; if (tempNumber < 0) { tempNumber += base; carry = 1; } else carry = 0; difference.setDigit(i, tempNumber); } difference.updateDigits(); difference.setBase(base); return difference; }
bignum addNumbers(const bignum &bn1, const bignum &bn2) { if (bn1.getBase() != bn2.getBase()) return addNumbers(bn1, bn2.getConverted(bn1.getBase())); if (bn1.absolute() == bn2.absolute()) { // -12 + 12 or 12 + -12 ---> 0 if (bn1.isNegative() != bn2.isNegative()) { bignum temp; temp.setBase(bn1.getBase()); return temp; } // -12 + -12 ---> -(12 + 12) if (bn1.isNegative() && bn2.isNegative()) { bignum temp(addNumbers(bn1.absolute(), bn2.absolute())); temp.setNegative(); temp.updateDigits(); return temp; } } if (bn1.absolute() > bn2.absolute()) { // -12 + 8 ---> -(12 - 8) if (bn1.isNegative() && !bn2.isNegative()) { bignum temp = subtractNumbers(bn1.absolute(), bn2.absolute()); temp.setNegative(); temp.updateDigits(); return temp; } // 12 + -8 ---> 12 - 8 if (!bn1.isNegative() && bn2.isNegative()) return subtractNumbers(bn1.absolute(), bn2.absolute()); // -12 + -8 ---> -(12 + 8) if (bn1.isNegative()&& bn2.isNegative()) { bignum temp = addNumbers(bn1.absolute(), bn2.absolute()); temp.setNegative(); temp.updateDigits(); return temp; } } if (bn1.absolute() < bn2.absolute()) { // -8 + 12 ---> 12 - 8 if (bn1.isNegative() && !bn2.isNegative()) { bignum temp = subtractNumbers(bn2.absolute(), bn1.absolute()); temp.updateDigits(); return temp; } // 8 + -12 ---> 8 - 12 if (!bn1.isNegative() && bn2.isNegative()) return subtractNumbers(bn1.absolute(), bn2.absolute()); // -8 + -12 ---> -(8 + 12) if (bn1.isNegative() && bn2.isNegative()) { bignum temp = addNumbers(bn1.absolute(), bn2.absolute()); temp.setNegative(); temp.updateDigits(); return temp; } } int carry = 0; int digits = 0; int decimal = 0; //sets decimal and digit values to the highest of each number decimal = (bn1.getDecimalCount() > bn2.getDecimalCount() ? bn1.getDecimalCount() : bn2.getDecimalCount()); digits = (bn1.getDigitCount() > bn2.getDigitCount() ? bn1.getDigitCount() + 1 : bn2.getDigitCount() + 1); bignum sum; int base = bn1.getBase(); for (int i = (ONES_PLACE - decimal); i < digits + 1 ; i++) { if (i >= MAXDIGITS) throw error_handler(__FILE__, __LINE__, "The value being calculated is too large for the settings provided"); int tempNumber = bn1.getDigit(i) + bn2.getDigit(i); tempNumber += carry; if (tempNumber>(base - 1)) { tempNumber -= base; carry = 1; } else carry = 0; sum.setDigit(i, tempNumber); } sum.updateDigits(); sum.setBase(base); return sum; }