]>
git.proxmox.com Git - ceph.git/blob - ceph/src/rapidjson/test/unittest/strtodtest.cpp
1 // Tencent is pleased to support the open source community by making RapidJSON available.
3 // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
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
8 // http://opensource.org/licenses/MIT
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.
17 #include "rapidjson/internal/strtod.h"
21 RAPIDJSON_DIAG_OFF(unreachable
-code
)
24 #define BIGINTEGER_LITERAL(s) BigInteger(s, sizeof(s) - 1)
26 using namespace rapidjson::internal
;
28 TEST(Strtod
, CheckApproximationCase
) {
29 static const int kSignificandSize
= 52;
30 static const int kExponentBias
= 0x3FF;
31 static const uint64_t kExponentMask
= RAPIDJSON_UINT64_C2(0x7FF00000, 0x00000000);
32 static const uint64_t kSignificandMask
= RAPIDJSON_UINT64_C2(0x000FFFFF, 0xFFFFFFFF);
33 static const uint64_t kHiddenBit
= RAPIDJSON_UINT64_C2(0x00100000, 0x00000000);
35 // http://www.exploringbinary.com/using-integers-to-check-a-floating-point-approximation/
36 // Let b = 0x1.465a72e467d88p-149
37 // = 5741268244528520 x 2^-201
42 u
.u
= 0x465a72e467d88 | ((static_cast<uint64_t>(-149 + kExponentBias
)) << kSignificandSize
);
44 const uint64_t bInt
= (u
.u
& kSignificandMask
) | kHiddenBit
;
45 const int bExp
= static_cast<int>(((u
.u
& kExponentMask
) >> kSignificandSize
) - kExponentBias
- kSignificandSize
);
46 EXPECT_DOUBLE_EQ(1.7864e-45, b
);
47 EXPECT_EQ(RAPIDJSON_UINT64_C2(0x001465a7, 0x2e467d88), bInt
);
48 EXPECT_EQ(-201, bExp
);
50 // Let d = 17864 x 10-49
51 const char dInt
[] = "17864";
55 const int hExp
= bExp
- 1;
56 EXPECT_EQ(-202, hExp
);
65 // Adjust for decimal exponent
77 // Adjust for binary exponent
85 // Adjust for half ulp exponent
93 // Remove common power of two factor from all three scaled values
94 int common_Exp2
= std::min(dS_Exp2
, std::min(bS_Exp2
, hS_Exp2
));
95 dS_Exp2
-= common_Exp2
;
96 bS_Exp2
-= common_Exp2
;
97 hS_Exp2
-= common_Exp2
;
99 EXPECT_EQ(153, dS_Exp2
);
100 EXPECT_EQ(0, dS_Exp5
);
101 EXPECT_EQ(1, bS_Exp2
);
102 EXPECT_EQ(49, bS_Exp5
);
103 EXPECT_EQ(0, hS_Exp2
);
104 EXPECT_EQ(49, hS_Exp5
);
106 BigInteger dS
= BIGINTEGER_LITERAL(dInt
);
107 dS
.MultiplyPow5(static_cast<unsigned>(dS_Exp5
)) <<= static_cast<size_t>(dS_Exp2
);
110 bS
.MultiplyPow5(static_cast<unsigned>(bS_Exp5
)) <<= static_cast<size_t>(bS_Exp2
);
113 hS
.MultiplyPow5(static_cast<unsigned>(hS_Exp5
)) <<= static_cast<size_t>(hS_Exp2
);
115 EXPECT_TRUE(BIGINTEGER_LITERAL("203970822259994138521801764465966248930731085529088") == dS
);
116 EXPECT_TRUE(BIGINTEGER_LITERAL("203970822259994122305215569213032722473144531250000") == bS
);
117 EXPECT_TRUE(BIGINTEGER_LITERAL("17763568394002504646778106689453125") == hS
);
119 EXPECT_EQ(1, dS
.Compare(bS
));
122 EXPECT_FALSE(dS
.Difference(bS
, &delta
));
123 EXPECT_TRUE(BIGINTEGER_LITERAL("16216586195252933526457586554279088") == delta
);
124 EXPECT_TRUE(bS
.Difference(dS
, &delta
));
125 EXPECT_TRUE(BIGINTEGER_LITERAL("16216586195252933526457586554279088") == delta
);
127 EXPECT_EQ(-1, delta
.Compare(hS
));