int BigInteger::CompareTo(const BigInteger& a) const { if (m_sign && !a.m_sign) return 1; if (!m_sign && a.m_sign) return -1; int order = 0; if (Cardinality() < a.Cardinality()) { order = -1; } else if (Cardinality() > a.Cardinality()) { order = 1; } else { for (int i = Cardinality() - 1; i >= 0; i--) { if (m_digits[i] < a.m_digits[i]) { order = -1; break; } else if (m_digits[i] > a.m_digits[i]) { order = 1; break; } } } return (m_sign) ? order : -order; }
BigInteger operator/ (const BigInteger& a, const BigInteger& b) { BigInteger remainder; char* result = new char[1]; result[0] = '\0'; // need positive divisor BigInteger bAbs = b.Abs(); int pos = a.Cardinality() - 1; while (pos >= 0) { // append next digit from dividend to temporary divisor int len = (remainder.IsNull()) ? 1 : remainder.Cardinality() + 1; int* digits = new int[len]; // copy old digits for (int k = 0; k < len - 1; k++) digits[k + 1] = remainder.m_digits[k]; // fetch digit from dividend digits[0] = a.m_digits[pos]; remainder = BigInteger(true, digits, len); // TODO: Ob len hier stimmt, ist OFFEN // divide current dividend with divisor int n = 0; while (bAbs <= remainder) { n++; remainder -= bAbs; } // append digit to result string int slen = strlen(result); char* tmp = new char[slen + 2]; strcpy_s (tmp, slen + 2, result); tmp[slen] = '0' + n; tmp[slen + 1] = '\0'; delete[] result; result = tmp; // fetch next digit from divisor pos--; } BigInteger tmp (result); tmp.m_sign = (a.Sign() == b.Sign()) ? true : false; tmp.RemoveLeadingZeros(); return tmp; }
void Test_BigMersennePrime() { BigInteger mersenne (1); BigInteger two (2); for (int i = 0; i < 11213; i ++) mersenne = mersenne * two; mersenne = mersenne - 1; cout << "Mersenne: " << endl << mersenne << endl; cout << "Number of Digits: " << mersenne.Cardinality() << endl; }
// binary arithmetic operators BigInteger operator+ (const BigInteger& a, const BigInteger& b) { // handle sign and change operation if (a.Sign() != b.Sign()) return (a.Sign()) ? a - b.Abs() : b - a.Abs(); // allocate array int length = (a.Cardinality() >= b.Cardinality()) ? a.Cardinality() + 1 : b.Cardinality() + 1; int* digits = new int[length]; // add numbers digit per digit int carry = 0; for (int i = 0; i < length; i++) { if (i < a.Cardinality()) carry += a[i]; if (i < b.Cardinality()) carry += b[i]; digits[i] = carry % 10; carry /= 10; } BigInteger tmp (a.Sign(), digits, length); tmp.RemoveLeadingZeros(); return tmp; }
BigInteger operator* (const BigInteger& a, const BigInteger& b) { int length = a.Cardinality() + b.Cardinality(); int* digits = new int[length]; int carry = 0; for (int i = 0; i < length; i++) { digits[i] = carry; for (int j = 0; j < b.Cardinality(); j++) if (i - j >= 0 && i - j < a.Cardinality()) digits[i] += a[i - j] * b[j]; carry = digits[i] / 10; digits[i] %= 10; } bool sign = (a.Sign() == b.Sign()) ? true : false; BigInteger tmp (sign, digits, length); tmp.RemoveLeadingZeros(); return tmp; }
BigInteger operator- (const BigInteger& a, const BigInteger& b) { // handle sign and change operation if (a.Sign() != b.Sign()) return (a.Sign()) ? a + b.Abs() : -(a.Abs() + b); if (a.Abs() < b.Abs()) return (a.Sign()) ? -(b - a) : b.Abs() - a.Abs(); // create copy of minuend BigInteger tmp (a); // traverse digits of subtrahend for (int i = 0; i < b.Cardinality(); i++) { if (tmp[i] < b[i]) { if (tmp[i + 1] != 0) { tmp[i + 1]--; tmp[i] += 10; } else { // preceding digit is zero, cannot borrow directly int pos = i + 1; while (tmp[pos] == 0) pos++; // borrow indirectly for (int k = pos; k >= i + 1; k--) { tmp[k]--; tmp[k - 1] += 10; } } } // subtract current subtrahend digit from minuend digit tmp[i] -= b[i]; } tmp.RemoveLeadingZeros(); return tmp; }