bigdecimal.h 2.4 KB

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