ieee754.h 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  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 IsNanOrInf() const { return (u_ & kExponentMask) == kExponentMask; }
  36. bool IsNormal() const { return (u_ & kExponentMask) != 0 || Significand() == 0; }
  37. bool IsZero() const { return (u_ & (kExponentMask | kSignificandMask)) == 0; }
  38. uint64_t IntegerSignificand() const { return IsNormal() ? Significand() | kHiddenBit : Significand(); }
  39. int IntegerExponent() const { return (IsNormal() ? Exponent() : kDenormalExponent) - kSignificandSize; }
  40. uint64_t ToBias() const { return (u_ & kSignMask) ? ~u_ + 1 : u_ | kSignMask; }
  41. static int EffectiveSignificandSize(int order) {
  42. if (order >= -1021)
  43. return 53;
  44. else if (order <= -1074)
  45. return 0;
  46. else
  47. return order + 1074;
  48. }
  49. private:
  50. static const int kSignificandSize = 52;
  51. static const int kExponentBias = 0x3FF;
  52. static const int kDenormalExponent = 1 - kExponentBias;
  53. static const uint64_t kSignMask = RAPIDJSON_UINT64_C2(0x80000000, 0x00000000);
  54. static const uint64_t kExponentMask = RAPIDJSON_UINT64_C2(0x7FF00000, 0x00000000);
  55. static const uint64_t kSignificandMask = RAPIDJSON_UINT64_C2(0x000FFFFF, 0xFFFFFFFF);
  56. static const uint64_t kHiddenBit = RAPIDJSON_UINT64_C2(0x00100000, 0x00000000);
  57. union {
  58. double d_;
  59. uint64_t u_;
  60. };
  61. };
  62. } // namespace internal
  63. RAPIDJSON_NAMESPACE_END
  64. #endif // RAPIDJSON_IEEE754_