bigdecimal.h 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  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 =
  15. typename std::enable_if<std::numeric_limits<Int>::is_integer &&
  16. std::numeric_limits<Int>::is_signed,
  17. void *>::type;
  18. template <typename Int>
  19. using is_unsigned_t =
  20. typename std::enable_if<std::numeric_limits<Int>::is_integer &&
  21. !std::numeric_limits<Int>::is_signed,
  22. void *>::type;
  23. public:
  24. using data_type = std::vector<int32_t>;
  25. static bigdecimal const ZERO, ONE, NEGATIVE_ONE;
  26. static constexpr int32_t const MAX_SEG{999999999};
  27. static constexpr int32_t const OVER_SEG{1000000000};
  28. static constexpr int32_t const SEG_DIGITS{9};
  29. public:
  30. bigdecimal();
  31. template <typename Value>
  32. bigdecimal(Value && value, int32_t scale) : bigdecimal(value) {
  33. rescale(scale);
  34. }
  35. template <typename Int>
  36. bigdecimal(Int value, is_signed_t<Int> = nullptr)
  37. : bigdecimal(value < 0,
  38. static_cast<uint64_t>(value < 0 ? -value : value)) {}
  39. template <typename Int>
  40. bigdecimal(Int value, is_unsigned_t<Int> = nullptr)
  41. : bigdecimal(false, static_cast<uint64_t>(value)) {}
  42. bigdecimal(long double);
  43. bigdecimal(char const *);
  44. int32_t scale() const { return scale_; }
  45. void rescale(int32_t);
  46. void set_value(bigdecimal const &);
  47. bigdecimal operator-() const;
  48. friend bigdecimal operator+(bigdecimal, bigdecimal const &);
  49. friend bigdecimal operator-(bigdecimal, bigdecimal const &);
  50. friend bigdecimal operator*(bigdecimal, bigdecimal const &);
  51. friend bigdecimal operator/(bigdecimal, bigdecimal const &);
  52. friend bigdecimal & operator+=(bigdecimal &, bigdecimal const &);
  53. friend bigdecimal & operator-=(bigdecimal &, bigdecimal const &);
  54. friend bigdecimal & operator*=(bigdecimal &, bigdecimal const &);
  55. friend bigdecimal & operator/=(bigdecimal &, bigdecimal const &);
  56. friend bool operator==(bigdecimal const &, bigdecimal const &);
  57. friend bool operator!=(bigdecimal const &, bigdecimal const &);
  58. friend bool operator<=(bigdecimal const &, bigdecimal const &);
  59. friend bool operator<(bigdecimal const &, bigdecimal const &);
  60. friend bool operator>=(bigdecimal const &, bigdecimal const &);
  61. friend bool operator>(bigdecimal const &, bigdecimal const &);
  62. std::string to_string() const;
  63. private:
  64. bigdecimal(bool, uint64_t);
  65. void set_scale(int32_t);
  66. void subtract_impl(bigdecimal const &, bool);
  67. friend void swap(bigdecimal & rhs, bigdecimal & lhs) {
  68. using std::swap;
  69. swap(rhs.is_negative, lhs.is_negative);
  70. swap(rhs.scale_, lhs.scale_);
  71. swap(rhs.steps_, lhs.steps_);
  72. swap(rhs.data, lhs.data);
  73. }
  74. bool is_negative;
  75. int32_t scale_{0}, steps_{0};
  76. data_type data{};
  77. };
  78. }