Skip to content

Commit

Permalink
Added subtraction (preview) and cleaned up code
Browse files Browse the repository at this point in the history
  • Loading branch information
SomedudeX committed May 7, 2024
1 parent cbdb159 commit f3ffba4
Show file tree
Hide file tree
Showing 6 changed files with 82 additions and 52 deletions.
8 changes: 5 additions & 3 deletions include/variable_int.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ namespace vint {

int64_t to_long_long() const;

bool to_bool() const;

std::string to_string() const;

size_t bytes() const;
Expand All @@ -30,15 +32,15 @@ namespace vint {

public: /* Arithmetic operators */

Int operator+(const Int &other) const;
Int operator+(const Int& rhs) const;

Int &operator+=(const Int &other);
Int &operator+=(const Int& rhs);

Int operator++(int);

Int& operator++();

// Int operator-(const Int& other) const;
Int operator-(const Int& rhs) const;

// Int operator*(const Int& other);

Expand Down
40 changes: 40 additions & 0 deletions src/int_arithmetic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,4 +77,44 @@ namespace vint {
return *this;
}

Int Int::operator-(const Int& rhs) const {
// Define aliases for convenience and readability
const auto& lhs = *this;
const auto& longer = rhs.m_storage.size() > lhs.m_storage.size()
? rhs : lhs;
const auto& shorter = rhs.m_storage.size() <= lhs.m_storage.size()
? rhs : lhs;

Int ret = longer;
uint32_t borrow = 0;
for (size_t i = 0; i < shorter.m_storage.size(); i++) {
// Add from left to right (the least significant digits first) while keeping track of carries
if ((uint32_t) (ret.m_storage[i] - borrow) > ret.m_storage[i]
|| (uint32_t) (ret.m_storage[i] - shorter.m_storage[i]) > ret.m_storage[i]
|| (uint32_t) (ret.m_storage[i] - shorter.m_storage[i] - borrow) > ret.m_storage[i]) {
// If there is a carry, simply add onto the ret (taking advantage of integer overflow)
ret.m_storage[i] -= (shorter.m_storage[i] + borrow);
borrow = 1;
} else {
// If there is not a carry, add and set carry to 0
ret.m_storage[i] -= (shorter.m_storage[i] + borrow);
borrow = 0;
}
}

if (borrow == 0)
return ret;

for (size_t i = shorter.m_storage.size(); i <= ret.m_storage.size(); i++) {
if (ret.m_storage[i] == 0) {
ret.m_storage[i] = UINT32_MAX;
continue;
} else {
ret.m_storage[i]--;
break;
}
}

return ret;
}
}
3 changes: 2 additions & 1 deletion src/int_constructors.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,9 @@ namespace vint {
std::vector<uint8_t> num_vec(number.size());
for (size_t i = num_start; i < num_vec.size(); i++)
num_vec[i] = number[i] - '0';
while (num_vec != std::vector<uint8_t>({}))
while (!num_vec.empty()) {
m_storage.push_back(divide_vectors(num_vec, (uint64_t) (UINT32_MAX) + 1));
}
}

}
9 changes: 6 additions & 3 deletions src/int_methods.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,11 @@ namespace vint {
return (m_sign == sign::negative) ? -ret : ret;
}

std::string
Int::to_string() const {
bool Int::to_bool() const {
return !(*this);
}

std::string Int::to_string() const {
std::vector<uint8_t> ret = { 0 };
std::vector<uint8_t> power = { 1 };
for (const auto& digit : m_storage) {
Expand Down Expand Up @@ -102,6 +105,6 @@ namespace vint {
}

bool Int::operator!() const {
return *this == 0;
return *this != 0;
}
}
70 changes: 27 additions & 43 deletions src/vectors.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,52 +86,36 @@ std::vector<uint8_t> multiply_vectors(const std::vector<uint8_t>& num1, uint64_t
}

// Truncate leading zeros and return in a uint8_t vector
auto beg_nonzero = std::find_if_not(temp.begin(), temp.end(),
[](uint64_t digit) { return digit == 0; });
std::vector<uint8_t> ret(beg_nonzero, temp.end());
return ret.empty()
? std::vector<uint8_t>{ 0 } : ret;
int64_t beg_nonzero = temp.size();
for (size_t i = 0; i < temp.size(); i++) {
if (temp[i] != 0) {
beg_nonzero = i;
break;
}
}

temp.erase(temp.begin(), temp.begin() + beg_nonzero);
return temp.empty()
? std::vector<uint8_t>{ 0 } : std::vector<uint8_t>(temp.begin(), temp.end());
}

uint32_t divide_vectors(std::vector<uint8_t>& num, uint64_t divisor) {
std::vector<uint8_t> quotient(num.size());
// Num.size should remain constant for the loop to work
for (size_t i = 0; i < num.size(); i++) {
// Load the dividend into an integer to work with easier
uint64_t dividend = vec_to_int(std::vector<uint8_t>(num.begin(), num.begin() + i + 1));

quotient[i] = dividend / divisor;
uint64_t subtract = quotient[i] * divisor;
uint64_t new_dividend = dividend - subtract;

// Insert zero in front to retain num.size
std::vector<uint8_t> dividend_vec = int_to_vec(new_dividend);
for (size_t j = 0; j <= i; j++) {
if (j < i - dividend_vec.size() + 1) {
num[j] = 0;
} else {
num[j] = dividend_vec[j - (i - dividend_vec.size() + 1)];
}
uint64_t divide_vectors(std::vector<uint8_t>& dividend, uint64_t divisor) {
uint64_t remainder = 0;

for (size_t i = 0; i < dividend.size(); i++) {
uint64_t dividend_part = remainder * 10 + dividend[i];
dividend[i] = dividend_part / divisor;
remainder = dividend_part % divisor;
}

int64_t beg_nonzero = dividend.size();
for (size_t i = 0; i < dividend.size(); i++) {
if (dividend[i] != 0) {
beg_nonzero = i;
break;
}
}

auto beg_quotient_nonzero = std::find_if_not(
quotient.begin(), quotient.end(),
[](uint8_t& digit) { return digit == 0; }
);

auto beg_mod_nonzero = std::find_if_not(
num.begin(), num.end(),
[](uint8_t& digit) { return digit == 0; }
);

std::string temp_mod;
for (auto it = beg_mod_nonzero; it != num.end(); it++)
temp_mod += (char) ((uint32_t) *it + '0');
if (temp_mod.empty())
temp_mod = '0';
uint32_t mod = std::stoll(temp_mod);

num = std::vector<uint8_t>(beg_quotient_nonzero, quotient.end());
return mod;
dividend.erase(dividend.begin(), dividend.begin() + beg_nonzero);
return remainder;
}
4 changes: 2 additions & 2 deletions src/vectors.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ std::vector<uint8_t> int_to_vec(const uint32_t& integer);
// Multiplies the array num1 by a multiplier, returning the product in another array
std::vector<uint8_t> multiply_vectors(const std::vector<uint8_t>& num1, uint64_t multiplier);

// Divide num by divisor, storing the quotient in num and returns the remainder
uint32_t divide_vectors(std::vector<uint8_t>& num, uint64_t divisor);
// Divide num by divisor, storing the quotient in dividend and returns the remainder
uint64_t divide_vectors(std::vector<uint8_t>& dividend, uint64_t divisor);

// Adds the two arrays num_one and num_two, returning the sum in another array
std::vector<uint8_t> add_vectors(const std::vector<uint8_t>& num_one,
Expand Down

0 comments on commit f3ffba4

Please sign in to comment.