decimal128.hpp 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. /*************************************************************************
  2. *
  3. * Copyright 2019 Realm Inc.
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. *
  17. **************************************************************************/
  18. #ifndef REALM_DECIMAL_HPP
  19. #define REALM_DECIMAL_HPP
  20. #include <realm/string_data.hpp>
  21. #include <string>
  22. #include <cstring>
  23. #include "null.hpp"
  24. namespace realm {
  25. class Decimal128 {
  26. public:
  27. struct Bid64 {
  28. Bid64(uint64_t x)
  29. : w(x)
  30. {
  31. }
  32. uint64_t w;
  33. };
  34. struct Bid128 {
  35. uint64_t w[2];
  36. };
  37. Decimal128();
  38. explicit Decimal128(int64_t);
  39. explicit Decimal128(uint64_t);
  40. explicit Decimal128(int);
  41. explicit Decimal128(double);
  42. Decimal128(Bid128 coefficient, int exponent, bool sign);
  43. explicit Decimal128(Bid64);
  44. explicit Decimal128(StringData);
  45. explicit Decimal128(Bid128 val)
  46. {
  47. m_value = val;
  48. }
  49. Decimal128(null) noexcept;
  50. static Decimal128 nan(const char*);
  51. static bool is_valid_str(StringData) noexcept;
  52. bool is_null() const;
  53. bool is_nan() const;
  54. bool operator==(const Decimal128& rhs) const;
  55. bool operator!=(const Decimal128& rhs) const;
  56. bool operator<(const Decimal128& rhs) const;
  57. bool operator>(const Decimal128& rhs) const;
  58. bool operator<=(const Decimal128& rhs) const;
  59. bool operator>=(const Decimal128& rhs) const;
  60. int compare(const Decimal128& rhs) const;
  61. Decimal128 operator*(int64_t mul) const;
  62. Decimal128 operator*(size_t mul) const;
  63. Decimal128 operator*(int mul) const;
  64. Decimal128 operator*(Decimal128 mul) const;
  65. Decimal128& operator*=(Decimal128 mul)
  66. {
  67. return *this = *this * mul;
  68. }
  69. Decimal128 operator/(int64_t div) const;
  70. Decimal128 operator/(size_t div) const;
  71. Decimal128 operator/(int div) const;
  72. Decimal128 operator/(Decimal128 div) const;
  73. Decimal128& operator/=(Decimal128 div)
  74. {
  75. return *this = *this / div;
  76. }
  77. Decimal128& operator+=(Decimal128);
  78. Decimal128 operator+(Decimal128 rhs) const
  79. {
  80. auto ret(*this);
  81. ret += rhs;
  82. return ret;
  83. }
  84. Decimal128& operator-=(Decimal128);
  85. Decimal128 operator-(Decimal128 rhs) const
  86. {
  87. auto ret(*this);
  88. ret -= rhs;
  89. return ret;
  90. }
  91. std::string to_string() const;
  92. Bid64 to_bid64() const;
  93. const Bid128* raw() const
  94. {
  95. return &m_value;
  96. }
  97. Bid128* raw()
  98. {
  99. return &m_value;
  100. }
  101. void unpack(Bid128& coefficient, int& exponent, bool& sign) const noexcept;
  102. private:
  103. Bid128 m_value;
  104. void from_int64_t(int64_t val);
  105. };
  106. inline std::ostream& operator<<(std::ostream& ostr, const Decimal128& id)
  107. {
  108. ostr << id.to_string();
  109. return ostr;
  110. }
  111. } // namespace realm
  112. namespace std {
  113. template <>
  114. struct numeric_limits<realm::Decimal128> {
  115. static constexpr bool is_integer = false;
  116. static realm::Decimal128 lowest() noexcept
  117. {
  118. return realm::Decimal128("-Inf");
  119. }
  120. static realm::Decimal128 max() noexcept
  121. {
  122. return realm::Decimal128("+Inf");
  123. }
  124. };
  125. template <>
  126. struct hash<realm::Decimal128> {
  127. size_t operator()(const realm::Decimal128& d) const noexcept
  128. {
  129. return static_cast<size_t>(d.raw()->w[0] ^ d.raw()->w[1]);
  130. }
  131. };
  132. } // namespace std
  133. #endif /* REALM_DECIMAL_HPP */