ieee754.h 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. // Tencent is pleased to support the open source community by making RapidJSON
  2. // available.
  3. //
  4. // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All
  5. // rights reserved.
  6. //
  7. // Licensed under the MIT License (the "License"); you may not use this file
  8. // except in compliance with the License. You may obtain a copy of the License
  9. // at
  10. //
  11. // http://opensource.org/licenses/MIT
  12. //
  13. // Unless required by applicable law or agreed to in writing, software
  14. // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  15. // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  16. // License for the specific language governing permissions and limitations under
  17. // the License.
  18. #ifndef RAPIDJSON_IEEE754_
  19. #define RAPIDJSON_IEEE754_
  20. #include "../rapidjson.h"
  21. RAPIDJSON_NAMESPACE_BEGIN
  22. namespace internal {
  23. class Double {
  24. public:
  25. Double() {}
  26. Double(double d) : d_(d) {}
  27. Double(uint64_t u) : u_(u) {}
  28. double Value() const { return d_; }
  29. uint64_t Uint64Value() const { return u_; }
  30. double NextPositiveDouble() const {
  31. RAPIDJSON_ASSERT(!Sign());
  32. return Double(u_ + 1).Value();
  33. }
  34. bool Sign() const { return (u_ & kSignMask) != 0; }
  35. uint64_t Significand() const { return u_ & kSignificandMask; }
  36. int Exponent() const {
  37. return static_cast<int>(((u_ & kExponentMask) >> kSignificandSize) -
  38. kExponentBias);
  39. }
  40. bool IsNan() const {
  41. return (u_ & kExponentMask) == kExponentMask && Significand() != 0;
  42. }
  43. bool IsInf() const {
  44. return (u_ & kExponentMask) == kExponentMask && Significand() == 0;
  45. }
  46. bool IsNanOrInf() const { return (u_ & kExponentMask) == kExponentMask; }
  47. bool IsNormal() const {
  48. return (u_ & kExponentMask) != 0 || Significand() == 0;
  49. }
  50. bool IsZero() const { return (u_ & (kExponentMask | kSignificandMask)) == 0; }
  51. uint64_t IntegerSignificand() const {
  52. return IsNormal() ? Significand() | kHiddenBit : Significand();
  53. }
  54. int IntegerExponent() const {
  55. return (IsNormal() ? Exponent() : kDenormalExponent) - kSignificandSize;
  56. }
  57. uint64_t ToBias() const {
  58. return (u_ & kSignMask) ? ~u_ + 1 : u_ | kSignMask;
  59. }
  60. static int EffectiveSignificandSize(int order) {
  61. if (order >= -1021)
  62. return 53;
  63. else if (order <= -1074)
  64. return 0;
  65. else
  66. return order + 1074;
  67. }
  68. private:
  69. static const int kSignificandSize = 52;
  70. static const int kExponentBias = 0x3FF;
  71. static const int kDenormalExponent = 1 - kExponentBias;
  72. static const uint64_t kSignMask = RAPIDJSON_UINT64_C2(0x80000000, 0x00000000);
  73. static const uint64_t kExponentMask =
  74. RAPIDJSON_UINT64_C2(0x7FF00000, 0x00000000);
  75. static const uint64_t kSignificandMask =
  76. RAPIDJSON_UINT64_C2(0x000FFFFF, 0xFFFFFFFF);
  77. static const uint64_t kHiddenBit =
  78. RAPIDJSON_UINT64_C2(0x00100000, 0x00000000);
  79. union {
  80. double d_;
  81. uint64_t u_;
  82. };
  83. };
  84. } // namespace internal
  85. RAPIDJSON_NAMESPACE_END
  86. #endif // RAPIDJSON_IEEE754_