redid comparison without addition or subtraction due to realization that doing them relative could lead to cycle

This commit is contained in:
Pagwin 2024-12-11 16:16:01 -05:00
parent 01c0cbb0ec
commit 35efa772f0
No known key found for this signature in database
GPG key ID: 81137023740CA260

View file

@ -2,6 +2,7 @@
#include <cassert>
#include <cstddef>
#include <iostream>
#include <limits>
#include <sstream>
#include <string>
#define todo(msg) \
@ -59,8 +60,68 @@ public:
isNegative = rhs.isNegative;
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) {
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;
}
friend Integer &operator-=(Integer &lhs, Integer const &rhs) {
@ -129,17 +190,19 @@ public:
return ret;
}
friend bool operator<(Integer const &lhs, Integer const &rhs) {
Integer tmp = (lhs - rhs);
return tmp.isNegative && tmp != 0;
if (lhs.isNegative != rhs.isNegative) {
return lhs.isNegative;
} else {
return abs_lt(lhs, rhs);
}
}
friend bool operator>(Integer const &lhs, Integer const &rhs) {
Integer tmp = (rhs - lhs);
return tmp.isNegative && tmp != 0;
return rhs < lhs;
}
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 "
"0");
return (rhs - lhs) == 0;
auto l_true = lhs.true_size();
return l_true == rhs.true_size() &&
std::equal(lhs.bytes, lhs.bytes + l_true, rhs.bytes);
}
friend std::ostream &operator<<(std::ostream &lhs, Integer const &rhs) {