bigdecimal.h 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. //
  2. // bigdecimal.h
  3. // bigdecimal
  4. //
  5. // Created by Sam Jaffe on 7/3/17.
  6. //
  7. #pragma once
  8. #include <string>
  9. #include <vector>
  10. namespace math {
  11. class bigdecimal {
  12. private:
  13. template <typename Int>
  14. using is_signed_t = typename std::enable_if<std::numeric_limits<Int>::is_integer && std::numeric_limits<Int>::is_signed, void*>::type;
  15. template <typename Int>
  16. using is_unsigned_t = typename std::enable_if<std::numeric_limits<Int>::is_integer && !std::numeric_limits<Int>::is_signed, void*>::type;
  17. public:
  18. using data_type = std::vector<int32_t>;
  19. static bigdecimal const ZERO, ONE, NEGATIVE_ONE;
  20. static constexpr int32_t const MAX_SEG { 999999999};
  21. static constexpr int32_t const OVER_SEG {1000000000};
  22. static constexpr int32_t const SEG_DIGITS{ 9};
  23. public:
  24. bigdecimal();
  25. template <typename Value>
  26. bigdecimal(Value && value, int32_t scale)
  27. : bigdecimal(value) {
  28. rescale(scale);
  29. }
  30. template <typename Int>
  31. bigdecimal(Int value, is_signed_t<Int> = nullptr)
  32. : bigdecimal(value < 0, static_cast<uint64_t>(value < 0 ? -value : value)) {}
  33. template <typename Int>
  34. bigdecimal(Int value, is_unsigned_t<Int> = nullptr)
  35. : bigdecimal(false, static_cast<uint64_t>(value)) {}
  36. bigdecimal(long double);
  37. bigdecimal(char const *);
  38. int32_t scale() const { return scale_; }
  39. void rescale(int32_t);
  40. void set_value(bigdecimal const &);
  41. bigdecimal operator-() const;
  42. friend bigdecimal operator+(bigdecimal, bigdecimal const &);
  43. friend bigdecimal operator-(bigdecimal, bigdecimal const &);
  44. friend bigdecimal operator*(bigdecimal, bigdecimal const &);
  45. friend bigdecimal operator/(bigdecimal, bigdecimal const &);
  46. friend bigdecimal & operator+=(bigdecimal &, bigdecimal const &);
  47. friend bigdecimal & operator-=(bigdecimal &, bigdecimal const &);
  48. friend bigdecimal & operator*=(bigdecimal &, bigdecimal const &);
  49. friend bigdecimal & operator/=(bigdecimal &, bigdecimal const &);
  50. friend bool operator==(bigdecimal const &, bigdecimal const &);
  51. friend bool operator!=(bigdecimal const &, bigdecimal const &);
  52. friend bool operator<=(bigdecimal const &, bigdecimal const &);
  53. friend bool operator< (bigdecimal const &, bigdecimal const &);
  54. friend bool operator>=(bigdecimal const &, bigdecimal const &);
  55. friend bool operator> (bigdecimal const &, bigdecimal const &);
  56. std::string to_string() const;
  57. private:
  58. bigdecimal(bool, uint64_t);
  59. void set_scale(int32_t);
  60. void subtract_impl(bigdecimal const &, bool);
  61. friend void swap(bigdecimal & rhs, bigdecimal & lhs) {
  62. using std::swap;
  63. swap(rhs.is_negative, lhs.is_negative);
  64. swap(rhs.scale_, lhs.scale_);
  65. swap(rhs.steps_, lhs.steps_);
  66. swap(rhs.data, lhs.data);
  67. }
  68. bool is_negative;
  69. int32_t scale_{0}, steps_{0};
  70. data_type data{};
  71. };
  72. }