Electroneum
Toggle main menu visibility
Loading...
Searching...
No Matches
strtodtest.cpp
Go to the documentation of this file.
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
15
#include "
unittest.h
"
16
17
#include "
rapidjson/internal/strtod.h
"
18
19
#ifdef __clang__
20
RAPIDJSON_DIAG_PUSH
21
RAPIDJSON_DIAG_OFF(unreachable-code)
22
#endif
23
24
#define BIGINTEGER_LITERAL(s) BigInteger(s, sizeof(s) - 1)
25
26
using namespace
rapidjson::internal;
27
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);
34
35
// http://www.exploringbinary.com/using-integers-to-check-a-floating-point-approximation/
36
// Let b = 0x1.465a72e467d88p-149
37
// = 5741268244528520 x 2^-201
38
union
{
39
double
d;
40
uint64_t
u;
41
}u;
42
u.u = 0x465a72e467d88 | ((
static_cast<
uint64_t
>
(-149 + kExponentBias)) << kSignificandSize);
43
const
double
b = u.d;
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);
49
50
// Let d = 17864 x 10-49
51
const
char
dInt[] =
"17864"
;
52
const
int
dExp = -49;
53
54
// Let h = 2^(bExp-1)
55
const
int
hExp = bExp - 1;
56
EXPECT_EQ
(-202, hExp);
57
58
int
dS_Exp2 = 0;
59
int
dS_Exp5 = 0;
60
int
bS_Exp2 = 0;
61
int
bS_Exp5 = 0;
62
int
hS_Exp2 = 0;
63
int
hS_Exp5 = 0;
64
65
// Adjust for decimal exponent
66
if
(dExp >= 0) {
67
dS_Exp2 += dExp;
68
dS_Exp5 += dExp;
69
}
70
else
{
71
bS_Exp2 -= dExp;
72
bS_Exp5 -= dExp;
73
hS_Exp2 -= dExp;
74
hS_Exp5 -= dExp;
75
}
76
77
// Adjust for binary exponent
78
if
(bExp >= 0)
79
bS_Exp2 += bExp;
80
else
{
81
dS_Exp2 -= bExp;
82
hS_Exp2 -= bExp;
83
}
84
85
// Adjust for half ulp exponent
86
if
(hExp >= 0)
87
hS_Exp2 += hExp;
88
else
{
89
dS_Exp2 -= hExp;
90
bS_Exp2 -= hExp;
91
}
92
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;
98
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);
105
106
BigInteger dS =
BIGINTEGER_LITERAL
(dInt);
107
dS.MultiplyPow5(
static_cast<
unsigned
>
(dS_Exp5)) <<=
static_cast<
size_t
>
(dS_Exp2);
108
109
BigInteger bS(bInt);
110
bS.MultiplyPow5(
static_cast<
unsigned
>
(bS_Exp5)) <<=
static_cast<
size_t
>
(bS_Exp2);
111
112
BigInteger hS(1);
113
hS.MultiplyPow5(
static_cast<
unsigned
>
(hS_Exp5)) <<=
static_cast<
size_t
>
(hS_Exp2);
114
115
EXPECT_TRUE
(
BIGINTEGER_LITERAL
(
"203970822259994138521801764465966248930731085529088"
) == dS);
116
EXPECT_TRUE
(
BIGINTEGER_LITERAL
(
"203970822259994122305215569213032722473144531250000"
) == bS);
117
EXPECT_TRUE
(
BIGINTEGER_LITERAL
(
"17763568394002504646778106689453125"
) == hS);
118
119
EXPECT_EQ
(1, dS.Compare(bS));
120
121
BigInteger delta(0);
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);
126
127
EXPECT_EQ
(-1, delta.Compare(hS));
128
}
129
130
#ifdef __clang__
131
RAPIDJSON_DIAG_POP
132
#endif
EXPECT_EQ
#define EXPECT_EQ(val1, val2)
Definition
gtest.h:1922
EXPECT_DOUBLE_EQ
#define EXPECT_DOUBLE_EQ(val1, val2)
Definition
gtest.h:2031
EXPECT_TRUE
#define EXPECT_TRUE(condition)
Definition
gtest.h:1859
TEST
#define TEST(test_case_name, test_name)
Definition
gtest.h:2187
EXPECT_FALSE
#define EXPECT_FALSE(condition)
Definition
gtest.h:1862
RAPIDJSON_UINT64_C2
#define RAPIDJSON_UINT64_C2(high32, low32)
Construct a 64-bit literal by a pair of 32-bit integer.
Definition
rapidjson.h:294
uint64_t
unsigned __int64 uint64_t
Definition
stdint.h:136
strtod.h
BIGINTEGER_LITERAL
#define BIGINTEGER_LITERAL(s)
Definition
strtodtest.cpp:24
unittest.h
external
rapidjson
test
unittest
strtodtest.cpp
Generated on
for Electroneum by
1.17.0