19 #ifndef RAPIDJSON_DIYFP_H_ 20 #define RAPIDJSON_DIYFP_H_ 22 #include "../rapidjson.h" 25 #if defined(_MSC_VER) && defined(_M_AMD64) && !defined(__INTEL_COMPILER) 27 #pragma intrinsic(_BitScanReverse64) 28 #pragma intrinsic(_umul128) 36 RAPIDJSON_DIAG_OFF(effc++)
41 RAPIDJSON_DIAG_OFF(padded)
72 #if defined(_MSC_VER) && defined(_M_AMD64) 77 return DiyFp(h,
e + rhs.
e + 64);
78 #elif (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) && defined(__x86_64__) 79 __extension__
typedef unsigned __int128 uint128;
80 uint128 p =
static_cast<uint128
>(
f) * static_cast<uint128>(rhs.
f);
85 return DiyFp(h,
e + rhs.
e + 64);
96 uint64_t tmp = (bd >> 32) + (ad & M32) + (bc & M32);
98 return DiyFp(ac + (ad >> 32) + (bc >> 32) + (tmp >> 32),
e + rhs.
e + 64);
104 #if defined(_MSC_VER) && defined(_M_AMD64) 106 _BitScanReverse64(&index,
f);
107 return DiyFp(
f << (63 - index),
e - (63 - index));
108 #elif defined(__GNUC__) && __GNUC__ >= 4 109 int s = __builtin_clzll(
f);
113 while (!(
res.f & (static_cast<uint64_t>(1) << 63))) {
133 DiyFp pl =
DiyFp((
f << 1) + 1,
e - 1).NormalizeBoundary();
135 mi.
f <<= mi.
e - pl.
e;
153 return std::numeric_limits<double>::infinity();
177 static const uint64_t kCachedPowers_F[] = {
223 static const int16_t kCachedPowers_E[] = {
224 -1220, -1193, -1166, -1140, -1113, -1087, -1060, -1034, -1007, -980,
225 -954, -927, -901, -874, -847, -821, -794, -768, -741, -715,
226 -688, -661, -635, -608, -582, -555, -529, -502, -475, -449,
227 -422, -396, -369, -343, -316, -289, -263, -236, -210, -183,
228 -157, -130, -103, -77, -50, -24, 3, 30, 56, 83,
229 109, 136, 162, 189, 216, 242, 269, 295, 322, 348,
230 375, 402, 428, 455, 481, 508, 534, 561, 588, 614,
231 641, 667, 694, 720, 747, 774, 800, 827, 853, 880,
232 907, 933, 960, 986, 1013, 1039, 1066
235 return DiyFp(kCachedPowers_F[index], kCachedPowers_E[index]);
241 double dk = (-61 - e) * 0.30102999566398114 + 347;
242 int k =
static_cast<int>(dk);
246 unsigned index =
static_cast<unsigned>((k >> 3) + 1);
247 *K = -(-348 +
static_cast<int>(index << 3));
254 unsigned index =
static_cast<unsigned>(exp + 348) / 8u;
255 *outExp = -348 +
static_cast<int>(index) * 8;
265 RAPIDJSON_DIAG_OFF(padded)
271 #endif // RAPIDJSON_DIYFP_H_
DiyFp operator-(const DiyFp &rhs) const
#define RAPIDJSON_UINT64_C2(high32, low32)
Construct a 64-bit literal by a pair of 32-bit integer.
DiyFp operator*(const DiyFp &rhs) const
DiyFp(uint64_t fp, int exp)
static const int kDiySignificandSize
DiyFp GetCachedPower10(int exp, int *outExp)
DiyFp NormalizeBoundary() const
#define RAPIDJSON_NAMESPACE_BEGIN
provide custom rapidjson namespace (opening expression)
static const uint64_t kDpExponentMask
static const int kDpSignificandSize
static const uint64_t kDpSignificandMask
unsigned __int64 uint64_t
#define RAPIDJSON_NAMESPACE_END
provide custom rapidjson namespace (closing expression)
static const int kDpMaxExponent
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
static const int kDpDenormalExponent
void NormalizedBoundaries(DiyFp *minus, DiyFp *plus) const
static const int kDpExponentBias
DiyFp GetCachedPower(int e, int *K)
DiyFp GetCachedPowerByIndex(size_t index)
static const int kDpMinExponent
#define RAPIDJSON_ASSERT(x)
Assertion.
static const uint64_t kDpHiddenBit