ieee754.h 2.9 KB

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