| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697 |
- //
- // bigdecimal.h
- // bigdecimal
- //
- // Created by Sam Jaffe on 7/3/17.
- //
- #pragma once
- #include <string>
- #include <vector>
- #include "number_format.h"
- namespace math {
- class bigdecimal {
- private:
- template <typename Int>
- using is_signed_t =
- typename std::enable_if<std::numeric_limits<Int>::is_integer &&
- std::numeric_limits<Int>::is_signed,
- void *>::type;
- template <typename Int>
- using is_unsigned_t =
- typename std::enable_if<std::numeric_limits<Int>::is_integer &&
- !std::numeric_limits<Int>::is_signed,
- void *>::type;
- public:
- using data_type = std::vector<int32_t>;
- static bigdecimal const ZERO, ONE, NEGATIVE_ONE;
- static constexpr int32_t const MAX_SEG{999999999};
- static constexpr int32_t const OVER_SEG{1000000000};
- static constexpr int32_t const SEG_DIGITS{9};
- public:
- bigdecimal();
- template <typename Value>
- bigdecimal(Value && value, int32_t scale) : bigdecimal(value) {
- rescale(scale);
- }
- template <typename Int>
- bigdecimal(Int value, is_signed_t<Int> = nullptr)
- : bigdecimal(value < 0,
- static_cast<uint64_t>(value < 0 ? -value : value)) {}
- template <typename Int>
- bigdecimal(Int value, is_unsigned_t<Int> = nullptr)
- : bigdecimal(false, static_cast<uint64_t>(value)) {}
- bigdecimal(long double);
- bigdecimal(char const *);
- int32_t scale() const { return scale_; }
- void rescale(int32_t);
- void set_value(bigdecimal const &);
- bigdecimal operator-() const;
- friend bigdecimal operator+(bigdecimal, bigdecimal const &);
- friend bigdecimal operator-(bigdecimal, bigdecimal const &);
- friend bigdecimal operator*(bigdecimal, bigdecimal const &);
- friend bigdecimal operator/(bigdecimal, bigdecimal const &);
- friend bigdecimal & operator+=(bigdecimal &, bigdecimal const &);
- friend bigdecimal & operator-=(bigdecimal &, bigdecimal const &);
- friend bigdecimal & operator*=(bigdecimal &, bigdecimal const &);
- friend bigdecimal & operator/=(bigdecimal &, bigdecimal const &);
- friend bool operator==(bigdecimal const &, bigdecimal const &);
- friend bool operator!=(bigdecimal const &, bigdecimal const &);
- friend bool operator<=(bigdecimal const &, bigdecimal const &);
- friend bool operator<(bigdecimal const &, bigdecimal const &);
- friend bool operator>=(bigdecimal const &, bigdecimal const &);
- friend bool operator>(bigdecimal const &, bigdecimal const &);
- std::string to_string(number_format const & fmt = default_fmt) const;
- private:
- bigdecimal(bool, uint64_t);
- void set_scale(int32_t);
- void subtract_impl(bigdecimal const &, bool);
- friend void swap(bigdecimal & rhs, bigdecimal & lhs) {
- using std::swap;
- swap(rhs.is_negative, lhs.is_negative);
- swap(rhs.scale_, lhs.scale_);
- swap(rhs.steps_, lhs.steps_);
- swap(rhs.data, lhs.data);
- }
- bool is_negative;
- int32_t scale_{0}, steps_{0};
- data_type data{};
- };
- }
|