87 lines
2.4 KiB
C++
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);
|