redid comparison without addition or subtraction due to realization that doing them relative could lead to cycle
This commit is contained in:
parent
01c0cbb0ec
commit
35efa772f0
1 changed files with 71 additions and 8 deletions
79
integer.cpp
79
integer.cpp
|
@ -2,6 +2,7 @@
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <limits>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
#define todo(msg) \
|
#define todo(msg) \
|
||||||
|
@ -59,8 +60,68 @@ public:
|
||||||
isNegative = rhs.isNegative;
|
isNegative = rhs.isNegative;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
void expand() {
|
||||||
|
byte *new_buf = new byte[size + 1];
|
||||||
|
std::copy(bytes, bytes + size, new_buf);
|
||||||
|
size++;
|
||||||
|
delete[] bytes;
|
||||||
|
bytes = new_buf;
|
||||||
|
}
|
||||||
|
std::size_t true_size() const {
|
||||||
|
std::size_t ret = size;
|
||||||
|
if (bytes == nullptr) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
while (bytes[ret - 1] == 0 && ret > 1) {
|
||||||
|
ret--;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
friend bool abs_lt(Integer const &lhs, Integer const &rhs) {
|
||||||
|
std::size_t true_lhs_size = lhs.true_size();
|
||||||
|
std::size_t true_rhs_size = rhs.true_size();
|
||||||
|
if (true_lhs_size != true_rhs_size) {
|
||||||
|
return true_lhs_size < true_rhs_size;
|
||||||
|
}
|
||||||
|
if (true_lhs_size == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto idx = true_lhs_size - 1;
|
||||||
|
while (idx >= 0) {
|
||||||
|
if (lhs.bytes[idx] != rhs.bytes[idx]) {
|
||||||
|
return lhs.bytes[idx] < rhs.bytes[idx];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
friend Integer &operator+=(Integer &lhs, Integer const &rhs) {
|
friend Integer &operator+=(Integer &lhs, Integer const &rhs) {
|
||||||
todo("+=");
|
// TODO: negative numbers
|
||||||
|
bool overflow = false;
|
||||||
|
for (std::size_t i = 0; i < std::min(lhs.size, rhs.size); i++) {
|
||||||
|
if (std::numeric_limits<byte>::max() - lhs.bytes[i] <= rhs.bytes[i]) {
|
||||||
|
overflow = true;
|
||||||
|
} else if (std::numeric_limits<byte>::max() - lhs.bytes[i] -
|
||||||
|
(rhs.bytes[i]) <=
|
||||||
|
(overflow ? 1 : 0)) {
|
||||||
|
overflow = true;
|
||||||
|
}
|
||||||
|
lhs.bytes[i] += rhs.bytes[i] + (overflow ? 1 : 0);
|
||||||
|
}
|
||||||
|
if (overflow) {
|
||||||
|
std::size_t idx = std::min(lhs.size, rhs.size);
|
||||||
|
if (idx == lhs.size) {
|
||||||
|
lhs.expand();
|
||||||
|
}
|
||||||
|
lhs.bytes[idx]++;
|
||||||
|
if (lhs.bytes[idx] == 0) {
|
||||||
|
idx++;
|
||||||
|
if (idx == lhs.size) {
|
||||||
|
lhs.expand();
|
||||||
|
}
|
||||||
|
lhs.bytes[idx]++;
|
||||||
|
}
|
||||||
|
}
|
||||||
return lhs;
|
return lhs;
|
||||||
}
|
}
|
||||||
friend Integer &operator-=(Integer &lhs, Integer const &rhs) {
|
friend Integer &operator-=(Integer &lhs, Integer const &rhs) {
|
||||||
|
@ -129,17 +190,19 @@ public:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
friend bool operator<(Integer const &lhs, Integer const &rhs) {
|
friend bool operator<(Integer const &lhs, Integer const &rhs) {
|
||||||
Integer tmp = (lhs - rhs);
|
if (lhs.isNegative != rhs.isNegative) {
|
||||||
return tmp.isNegative && tmp != 0;
|
return lhs.isNegative;
|
||||||
|
} else {
|
||||||
|
return abs_lt(lhs, rhs);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
friend bool operator>(Integer const &lhs, Integer const &rhs) {
|
friend bool operator>(Integer const &lhs, Integer const &rhs) {
|
||||||
Integer tmp = (rhs - lhs);
|
return rhs < lhs;
|
||||||
return tmp.isNegative && tmp != 0;
|
|
||||||
}
|
}
|
||||||
friend bool operator==(Integer const &lhs, Integer const &rhs) {
|
friend bool operator==(Integer const &lhs, Integer const &rhs) {
|
||||||
todo("need to actually do a check for the case that one or both of them is "
|
auto l_true = lhs.true_size();
|
||||||
"0");
|
return l_true == rhs.true_size() &&
|
||||||
return (rhs - lhs) == 0;
|
std::equal(lhs.bytes, lhs.bytes + l_true, rhs.bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
friend std::ostream &operator<<(std::ostream &lhs, Integer const &rhs) {
|
friend std::ostream &operator<<(std::ostream &lhs, Integer const &rhs) {
|
||||||
|
|
Loading…
Reference in a new issue