/*************************************************************************** * Copyright (C) 2005 by Jeff Ferr * * root@sat * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include "jbiginteger.h" #include "jmathlib.h" namespace jmath { BigInteger::BigInteger(std::string value, int radix) { if (value == "") { _integer = NULL; _integer_length = 0; return; } if (IsValid(value, radix) == false) { return; } int i, k, l, m, count; const char *p; _integer_length = value.size(); _integer = new uint8_t[_integer_length]; count = 0; p = value.c_str(); for (i=_integer_length-1; i>=0; i-=2) { k = (p[i-0] - '0') & 0x0f; l = (p[i-1] - '0') & 0x0f; m = ((k << 4) | l) & 0xff; _integer[count++] = (uint8_t)m; } } BigInteger::~BigInteger() { } bool BigInteger::IsValid(std::string value, int radix) { if (radix != 10) { return false; } return true; } BigInteger * BigInteger::ProbablePrime(int length) { return NULL; } BigInteger * BigInteger::NextProbablePrime() { return NULL; } bool BigInteger::operator==(const BigInteger &value) { return false; } bool BigInteger::operator>(const BigInteger &value) { return false; } bool BigInteger::operator<(const BigInteger &value) { return false; } BigInteger & BigInteger::operator+(BigInteger &value) { int a, b, c, d, e, f, i, count, carry, max, min; uint8_t *p0, *p1, *p2, *tmp; if ((this->IsNegative() == false && const_cast(&value)->IsNegative() == true) || (this->IsNegative() == true && const_cast(&value)->IsNegative() == false)) { return (*this - value); } BigInteger *bint = new BigInteger(""); p0 = _integer; p1 = const_cast(&value)->_integer; max = _integer_length; min = const_cast(&value)->GetBitLength()/8; tmp = p0; if (_integer_length < min) { max = min; min = _integer_length; tmp = p1; } p2 = new uint8_t[max + 1]; memcpy(p2, tmp, max); carry = 0; for (i=0; i<=min/2; i++) { a = (p0[i] >> 4) & 0x0f; b = (p0[i] >> 0) & 0x0f; c = (p1[i] >> 4) & 0x0f; d = (p1[i] >> 0) & 0x0f; e = a + c + carry; if (e > 9) { e = e - 10; carry = 1; } else { carry = 0; } f = b + d + carry; if (f > 9) { f = f - 10; carry = 1; } else { carry = 0; } p2[i] = e << 4 | f; } count = 0; for (i=min/2+1; i<=max/2; i++) { count++; if (carry == 0) { bint->_integer = p2; bint->_integer_length = max; return *bint; } p2[i] = p2[i] + carry; if (p2[i] > 9) { p2[i] = p2[i] - 10; carry = 1; } else { carry = 0; } } bint->_integer = p2; bint->_integer_length = max + count; return *bint; } BigInteger & BigInteger::operator-(BigInteger &value) { int a, b, c, d, e, f, i, count, carry, max, min; uint8_t *p0, *p1, *p2, *tmp; BigInteger *bint = new BigInteger(""), *bmin = NULL, *bmax = NULL; *bmin = *this; *bmax = value; if (*this < value) { *bmin = value; *bmax = *this; } p0 = _integer; p1 = const_cast(&value)->_integer; max = _integer_length; min = const_cast(&value)->GetBitLength()/8; tmp = p0; if (_integer_length < min) { max = min; min = _integer_length; tmp = p1; } p2 = new uint8_t[max + 1]; memcpy(p2, tmp, max); carry = 0; for (i=0; i<=min/2; i++) { a = (p0[i] >> 4) & 0x0f; b = (p0[i] >> 0) & 0x0f; c = (p1[i] >> 4) & 0x0f; d = (p1[i] >> 0) & 0x0f; e = a + c + carry; if (e > 9) { e = e - 10; carry = 1; } else { carry = 0; } f = b + d + carry; if (f > 9) { f = f - 10; carry = 1; } else { carry = 0; } p2[i] = e << 4 | f; } count = 0; for (i=min/2+1; i<=max/2; i++) { count++; if (carry == 0) { bint->_integer = p2; bint->_integer_length = max; return *bint; } p2[i] = p2[i] + carry; if (p2[i] > 9) { p2[i] = p2[i] - 10; carry = 1; } else { carry = 0; } } bint->_integer = p2; bint->_integer_length = max + count; return *bint; } BigInteger & BigInteger::Divide(BigInteger *value) { return *this; } BigInteger & BigInteger::DivideAndRemainder(BigInteger *value) { // TODO:: ver return *this; } BigInteger & BigInteger::Remainder(BigInteger *value) { // TODO:: ver return *this; } BigInteger & BigInteger::Pow(int exponent) { return *this; } BigInteger & BigInteger::GCD(BigInteger *value) { return *this; } BigInteger & BigInteger::Absolute() { return *this; } BigInteger & BigInteger::Negate() { return *this; } bool BigInteger::IsNegative() { return false; } BigInteger & BigInteger::Mod(BigInteger *value) { return *this; } BigInteger & BigInteger::ShiftLeft(int n) { return *this; } BigInteger & BigInteger::ShiftRight(int n) { return *this; } BigInteger & BigInteger::And(BigInteger *value) { return *this; } BigInteger & BigInteger::Or(BigInteger *value) { return *this; } BigInteger & BigInteger::Xor(BigInteger *value) { return *this; } BigInteger & BigInteger::Not() { return *this; } BigInteger & BigInteger::AndNot(BigInteger *value) { return *this; } bool BigInteger::TestBit(int n) { return false; } BigInteger & BigInteger::SetBit(int n) { return *this; } BigInteger & BigInteger::ClearBit(int n) { return *this; } BigInteger & BigInteger::FlipBit(int n) { return *this; } int BigInteger::GetLowestSetBit() { return 0; } int BigInteger::GetBitLength() { return 0; } bool BigInteger::IsProbablePrime(int certainty) { return false; } int BigInteger::Compare(jcommon::Object *o) { return 0; } bool BigInteger::Equals(jcommon::Object *o) { return false; } BigInteger & BigInteger::Minimum(BigInteger *value) { return *this; } BigInteger & BigInteger::Maximum(BigInteger *value) { return *this; } unsigned long long BigInteger::Hash() { return 0; } std::string BigInteger::what(int radix) { return ""; } std::string BigInteger::what() { std::ostringstream o; int i, a, b; if ((_integer_length % 2) != 0) { o << (int)((_integer[_integer_length/2] >> 0) & 0x0f); } for (i=_integer_length/2-1; i>=0; i--) { a = (_integer[i] >> 4) & 0x0f; b = (_integer[i] >> 0) & 0x0f; o << (int)b << (int)a; } return o.str(); } long long BigInteger::GetValue() { return 0LL; } };