Skip to content

Commit

Permalink
major fixes for big integer all tests passing
Browse files Browse the repository at this point in the history
  • Loading branch information
abumq committed Sep 15, 2017
1 parent db40804 commit c171438
Show file tree
Hide file tree
Showing 8 changed files with 170 additions and 50 deletions.
57 changes: 50 additions & 7 deletions package/mine.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1330,15 +1330,27 @@ BigInteger BigInteger::operator-(const BigInteger& other) const
BigInteger thisCopy(*this);
thisCopy.m_negative = false;

return thisCopy + otherCopy;
BigInteger result;
if (thisCopy > otherCopy) {
result = thisCopy + otherCopy;
} else {
result = otherCopy + thisCopy;
result.m_negative = m_negative; // previously negative or not
}
return result;
} else if (m_negative && other.m_negative) {
BigInteger otherCopy(other);
otherCopy.m_negative = false;
BigInteger thisCopy(*this);
thisCopy.m_negative = false;

BigInteger result = thisCopy + otherCopy;
result.m_negative = true;
BigInteger result;
if (thisCopy > otherCopy) {
result = thisCopy - otherCopy;
result.m_negative = true;
} else {
result = otherCopy - thisCopy;
}
return result;
}
Container data;
Expand Down Expand Up @@ -1500,10 +1512,12 @@ BigInteger BigInteger::divide_(const BigInteger& dividend, const BigInteger& div
r = 0;
return isNeg ? -1 : 1;
} else if (tdividend < tdivisor) {
r = tdividend < 0 ? tdividend * -1 : tdividend;
r = tdividend;
r.m_negative = dividend.isNegative();
return 0;
}
while (tdivisor << 1 <= tdividend) {
// add two checks to reduce unneeded shifting
while (!tdivisor.isZero() && tdivisor << 1 <= tdividend) {
tdivisor <<= 1;
quotient <<= 1;
}
Expand All @@ -1528,7 +1542,7 @@ void BigInteger::divide(BigInteger n, BigInteger d, BigInteger& q, BigInteger& r
}


if (d > 0 && d < 10) {
if (d < 10) {
int di = static_cast<int>(d.toLong());
int rem = 0;
int quo = 0;
Expand All @@ -1547,14 +1561,32 @@ void BigInteger::divide(BigInteger n, BigInteger d, BigInteger& q, BigInteger& r
}
r = rem;
} else {
q = divide_(n, d, d, r);
//q = divide_(n, d, d, r);

q = 0;
long long pos = -1;
while (d < n){
d <<= 1;
++pos;
}
d >>= 1;
while (pos > -1) {
if (n >= d) {
q += 1 << pos;
n -= d;
}
d >>= 1;
--pos;
}
r = n;
}

while (!q.m_data.empty() && q.m_data[0] == 0) {
q.m_data.erase(std::find_if_not(q.m_data.begin(), q.m_data.end(), [&](int c) -> bool {
return c > 0;
}));
}
q.checkAndFixData();
}

BigInteger BigInteger::operator/(const BigInteger& d) const
Expand Down Expand Up @@ -1733,6 +1765,17 @@ bool BigInteger::isZero() const
return iter == m_data.end();
}

unsigned int BigInteger::bitCount() const
{
auto b = bin();
unsigned int bits = 0;
while (b.any()) {
bits++;
b >>= 1;
}
return bits;
}

// ----------------------------- comparison ----------------------------------------

int BigInteger::compare(const BigInteger& other) const
Expand Down
19 changes: 13 additions & 6 deletions package/mine.h
Original file line number Diff line number Diff line change
Expand Up @@ -884,7 +884,7 @@ class AES {
/// ******************** DESIGN IS SUBJECT TO CHANGE ****************************
///
class BigInteger {
static const std::size_t kMaxSizeInBits = 256; // todo: change to template
static const std::size_t kMaxSizeInBits = 4096; // todo: change to template
using BigIntegerBitSet = std::bitset<kMaxSizeInBits>;
using Container = std::vector<int>;
public:
Expand Down Expand Up @@ -984,7 +984,7 @@ class BigInteger {
inline bool isNegative() const { return m_negative; }
inline std::size_t digits() const { return m_data.size(); }
inline bool isZero() const;
unsigned long bitCount() const;
unsigned int bitCount() const;

///
/// \return Whether it's 1, 10, 100, 1000, ...
Expand Down Expand Up @@ -1074,6 +1074,10 @@ class MathHelper {
if (gcdResult != 1) {
throw std::invalid_argument("Inverse does not exist");
}
/*std::cout << x << std::endl;
std::cout << (x % m) << std::endl;
std::cout << (x % m) + m << std::endl;
std::cout << ((x % m) + m) % m << std::endl;*/
return ((x % m) + m) % m;
}

Expand Down Expand Up @@ -1107,6 +1111,8 @@ class MathHelper {
BigIntegerT x1, y1;
BigIntegerT gcd = gcdExtended(b % a, a, &x1, &y1);

/*std::cout << y1 << " - " << ((b / a) * x1) << " = " << (y1 - ((b / a) * x1)) << std::endl;
std::cout << std::endl;*/
*x = y1 - ((b / a) * x1);
*y = x1;

Expand Down Expand Up @@ -1171,20 +1177,21 @@ class MathHelper {
///
/// \brief Counts number of bits in big integer
///
virtual unsigned int countBits(BigIntegerT b) const
virtual unsigned int countBits(const BigIntegerT& b) const
{
BigIntegerT bc(b);
unsigned int bits = 0;
while (b > 0) {
while (bc > 0) {
bits++;
b = b >> 1;
bc = bc >> 1;
}
return bits;
}

///
/// \brief Count number of bytes in big integer
///
virtual inline unsigned int countBytes(BigIntegerT b) const
virtual inline unsigned int countBytes(const BigIntegerT& b) const
{
return countBits(b) * 8;
}
Expand Down
39 changes: 35 additions & 4 deletions src/big-integer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -424,10 +424,12 @@ BigInteger BigInteger::divide_(const BigInteger& dividend, const BigInteger& div
r = 0;
return isNeg ? -1 : 1;
} else if (tdividend < tdivisor) {
r = tdividend < 0 ? tdividend * -1 : tdividend;
r = tdividend;
r.m_negative = dividend.isNegative();
return 0;
}
while (tdivisor << 1 <= tdividend) {
// add two checks to reduce unneeded shifting
while (!tdivisor.isZero() && tdivisor << 1 <= tdividend) {
tdivisor <<= 1;
quotient <<= 1;
}
Expand All @@ -452,7 +454,7 @@ void BigInteger::divide(BigInteger n, BigInteger d, BigInteger& q, BigInteger& r
}


if (d > 0 && d < 10) {
if (d < 10) {
int di = static_cast<int>(d.toLong());
int rem = 0;
int quo = 0;
Expand All @@ -471,14 +473,32 @@ void BigInteger::divide(BigInteger n, BigInteger d, BigInteger& q, BigInteger& r
}
r = rem;
} else {
q = divide_(n, d, d, r);
//q = divide_(n, d, d, r);

q = 0;
long long pos = -1;
while (d < n){
d <<= 1;
++pos;
}
d >>= 1;
while (pos > -1) {
if (n >= d) {
q += 1 << pos;
n -= d;
}
d >>= 1;
--pos;
}
r = n;
}

while (!q.m_data.empty() && q.m_data[0] == 0) {
q.m_data.erase(std::find_if_not(q.m_data.begin(), q.m_data.end(), [&](int c) -> bool {
return c > 0;
}));
}
q.checkAndFixData();
}

BigInteger BigInteger::operator/(const BigInteger& d) const
Expand Down Expand Up @@ -657,6 +677,17 @@ bool BigInteger::isZero() const
return iter == m_data.end();
}

unsigned int BigInteger::bitCount() const
{
auto b = bin();
unsigned int bits = 0;
while (b.any()) {
bits++;
b >>= 1;
}
return bits;
}

// ----------------------------- comparison ----------------------------------------

int BigInteger::compare(const BigInteger& other) const
Expand Down
4 changes: 2 additions & 2 deletions src/big-integer.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ namespace mine {
/// ******************** DESIGN IS SUBJECT TO CHANGE ****************************
///
class BigInteger {
static const std::size_t kMaxSizeInBits = 256; // todo: change to template
static const std::size_t kMaxSizeInBits = 4096; // todo: change to template
using BigIntegerBitSet = std::bitset<kMaxSizeInBits>;
using Container = std::vector<int>;
public:
Expand Down Expand Up @@ -138,7 +138,7 @@ class BigInteger {
inline bool isNegative() const { return m_negative; }
inline std::size_t digits() const { return m_data.size(); }
inline bool isZero() const;
unsigned long bitCount() const;
unsigned int bitCount() const;

///
/// \return Whether it's 1, 10, 100, 1000, ...
Expand Down
18 changes: 11 additions & 7 deletions src/rsa.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,10 @@ class MathHelper {
if (gcdResult != 1) {
throw std::invalid_argument("Inverse does not exist");
}
//std::cout << x << std::endl;
/*std::cout << x << std::endl;
std::cout << (x % m) << std::endl;
std::cout << (x % m) + m << std::endl;
std::cout << ((x % m) + m) % m << std::endl;*/
return ((x % m) + m) % m;
}

Expand Down Expand Up @@ -123,8 +126,8 @@ class MathHelper {
BigIntegerT x1, y1;
BigIntegerT gcd = gcdExtended(b % a, a, &x1, &y1);

//std::cout << y1 << " - " << ((b / a) * x1) << " = " << (y1 - ((b / a) * x1)) << std::endl;
//std::cout << std::endl;
/*std::cout << y1 << " - " << ((b / a) * x1) << " = " << (y1 - ((b / a) * x1)) << std::endl;
std::cout << std::endl;*/
*x = y1 - ((b / a) * x1);
*y = x1;

Expand Down Expand Up @@ -189,20 +192,21 @@ class MathHelper {
///
/// \brief Counts number of bits in big integer
///
virtual unsigned int countBits(BigIntegerT b) const
virtual unsigned int countBits(const BigIntegerT& b) const
{
BigIntegerT bc(b);
unsigned int bits = 0;
while (b > 0) {
while (bc > 0) {
bits++;
b = b >> 1;
bc = bc >> 1;
}
return bits;
}

///
/// \brief Count number of bytes in big integer
///
virtual inline unsigned int countBytes(BigIntegerT b) const
virtual inline unsigned int countBytes(const BigIntegerT& b) const
{
return countBits(b) * 8;
}
Expand Down
Loading

0 comments on commit c171438

Please sign in to comment.