erick-alcachofa 32fe4db4f2
BigInt implementation
Signed-off-by: erick-alcachofa <erick@artichoke.dev>
2025-09-09 03:29:44 +00:00

87 lines
2.4 KiB
C++

#pragma once
#include <expected>
#include <string>
#include <string_view>
#include <vector>
#include <strings.hpp>
#include <types.hpp>
struct BigInt {
static constexpr u32 Base = 100;
bool isNegative = false;
std::vector<u8> digits;
struct DivisionResult;
friend BigInt operator+(const BigInt &, const BigInt &);
friend BigInt operator-(const BigInt &, const BigInt &);
friend BigInt operator*(const BigInt &, const BigInt &);
friend std::strong_ordering operator<=>(const BigInt &lhs, const BigInt &rhs);
static std::expected<BigInt, std::string>
fromString(std::string_view value);
static std::expected<BigInt, std::string>
fromInteger(std::integral auto value) {
auto str = std::to_string(value);
return BigInt::fromString(str);
}
std::string toString() const;
inline bool isZero() const noexcept {
return digits.empty();
}
BigInt() = default;
BigInt(BigInt &&) = default;
BigInt(const BigInt &) = default;
BigInt &operator=(BigInt &&) = default;
BigInt &operator=(const BigInt &) = default;
~BigInt() = default;
static std::expected<DivisionResult, std::string> divmod(const BigInt &lhs,
const BigInt &rhs);
static std::expected<BigInt, std::string> quotient(const BigInt &lhs,
const BigInt &rhs);
static std::expected<BigInt, std::string> remainder(const BigInt &lhs,
const BigInt &rhs);
private:
void trimLeadingZeroes() noexcept;
inline u64 size() const noexcept {
return this->digits.size();
}
static BigInt addMagnitudes(const BigInt &lhs, const BigInt &rhs);
static BigInt subMagnitudes(const BigInt &lhs, const BigInt &rhs);
static BigInt multiplyMagnitudes(const BigInt &lhs, const BigInt &rhs);
static std::strong_ordering compareMagnitudes(const BigInt &lhs,
const BigInt &rhs) noexcept;
};
struct BigInt::DivisionResult {
BigInt quotient;
BigInt remainder;
};
BigInt operator+(const BigInt &lhs, const BigInt &rhs);
BigInt operator-(const BigInt &lhs, const BigInt &rhs);
BigInt operator*(const BigInt &lhs, const BigInt &rhs);
std::strong_ordering operator<=>(const BigInt &lhs, const BigInt &rhs);
bool operator==(const BigInt &lhs, const BigInt &rhs);
bool operator!=(const BigInt &lhs, const BigInt &rhs);