Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
R
rapidjson
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
rapidjson
Commits
40852f4d
Commit
40852f4d
authored
Nov 14, 2014
by
Milo Yip
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fixes StrtodDiyFp bugs
parent
b4e2d58c
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
23 additions
and
19 deletions
+23
-19
diyfp.h
include/rapidjson/internal/diyfp.h
+1
-1
ieee754.h
include/rapidjson/internal/ieee754.h
+4
-4
strtod.h
include/rapidjson/internal/strtod.h
+17
-11
readertest.cpp
test/unittest/readertest.cpp
+1
-3
No files found.
include/rapidjson/internal/diyfp.h
View file @
40852f4d
...
...
@@ -179,7 +179,7 @@ struct DiyFp {
static
const
int
kDpExponentBias
=
0x3FF
+
kDpSignificandSize
;
static
const
int
kDpMaxExponent
=
0x7FF
-
kDpExponentBias
;
static
const
int
kDpMinExponent
=
-
kDpExponentBias
;
static
const
int
kDpDenormalExponent
=
-
kDpExponentBias
-
1
;
static
const
int
kDpDenormalExponent
=
-
kDpExponentBias
+
1
;
static
const
uint64_t
kDpExponentMask
=
RAPIDJSON_UINT64_C2
(
0x7FF00000
,
0x00000000
);
static
const
uint64_t
kDpSignificandMask
=
RAPIDJSON_UINT64_C2
(
0x000FFFFF
,
0xFFFFFFFF
);
static
const
uint64_t
kDpHiddenBit
=
RAPIDJSON_UINT64_C2
(
0x00100000
,
0x00000000
);
...
...
include/rapidjson/internal/ieee754.h
View file @
40852f4d
...
...
@@ -61,12 +61,12 @@ public:
uint64_t
ToBias
()
const
{
return
(
u
&
kSignMask
)
?
~
u
+
1
:
u
|
kSignMask
;
}
static
unsigned
EffectiveSignificandSize
(
int
order
)
{
if
(
order
>=
kDenormalExponent
+
kSignificandSize
)
return
kSignificandSize
;
else
if
(
order
<=
kDenormalExponent
)
if
(
order
>=
-
1021
)
return
53
;
else
if
(
order
<=
-
1074
)
return
0
;
else
return
order
-
kDenormalExponent
;
return
order
+
1074
;
}
private
:
...
...
include/rapidjson/internal/strtod.h
View file @
40852f4d
...
...
@@ -146,27 +146,29 @@ inline bool StrtodFast(double d, int p, double* result) {
inline
bool
StrtodDiyFp
(
const
char
*
decimals
,
size_t
length
,
size_t
decimalPosition
,
int
exp
,
double
*
result
)
{
uint64_t
significand
=
0
;
size_t
i
=
0
;
// 2^64 - 1 = 18446744073709551615, 1844674407370955161 = 0x1999999999999999
for
(;
i
<
length
&&
(
significand
<
RAPIDJSON_UINT64_C2
(
0x19999999
,
0x99999999
)
||
decimals
[
i
]
<=
'4'
);
i
++
)
for
(;
i
<
length
;
i
++
)
{
if
(
significand
>
RAPIDJSON_UINT64_C2
(
0x19999999
,
0x99999999
)
||
significand
==
RAPIDJSON_UINT64_C2
(
0x19999999
,
0x99999999
)
&&
decimals
[
i
]
>
'5'
)
break
;
significand
=
significand
*
10
+
(
decimals
[
i
]
-
'0'
);
}
if
(
i
<
length
&&
decimals
[
i
]
>=
'5'
)
// Rounding
significand
++
;
DiyFp
v
(
significand
,
0
);
size_t
remaining
=
length
-
i
;
const
int
dExp
=
(
int
)
decimalPosition
-
(
int
)
i
+
exp
+
(
int
)
remaining
;
const
unsigned
kUlpShift
=
3
;
const
unsigned
kUlp
=
1
<<
kUlpShift
;
int
error
=
(
remaining
==
0
)
?
0
:
kUlp
/
2
;
DiyFp
v
(
significand
,
0
);
v
=
v
.
Normalize
();
error
<<=
-
v
.
e
;
error
<<=
-
v
.
e
;
const
int
dExp
=
(
int
)
decimalPosition
-
(
int
)
i
+
exp
;
int
actualExp
;
double
temp1
=
v
.
ToDouble
();
v
=
v
*
GetCachedPower10
(
dExp
,
&
actualExp
);
double
temp2
=
v
.
ToDouble
();
DiyFp
cachedPower
=
GetCachedPower10
(
dExp
,
&
actualExp
);
if
(
actualExp
!=
dExp
)
{
static
const
DiyFp
kPow10
[]
=
{
DiyFp
(
RAPIDJSON_UINT64_C2
(
0xa0000000
,
00000000
),
-
60
),
// 10^1
...
...
@@ -177,9 +179,13 @@ inline bool StrtodDiyFp(const char* decimals, size_t length, size_t decimalPosit
DiyFp
(
RAPIDJSON_UINT64_C2
(
0xf4240000
,
00000000
),
-
44
),
// 10^6
DiyFp
(
RAPIDJSON_UINT64_C2
(
0x98968000
,
00000000
),
-
40
)
// 10^7
};
v
=
v
*
kPow10
[
dExp
-
actualExp
-
1
];
int
adjustment
=
dExp
-
actualExp
-
1
;
v
=
v
*
kPow10
[
adjustment
];
if
(
length
+
adjustment
>
19
)
// has more digits than decimal digits in 64-bit
error
+=
kUlp
/
2
;
}
double
temp3
=
v
.
ToDouble
();
v
=
v
*
cachedPower
;
error
+=
kUlp
+
(
error
==
0
?
0
:
1
);
...
...
@@ -197,9 +203,9 @@ inline bool StrtodDiyFp(const char* decimals, size_t length, size_t decimalPosit
precisionSize
-=
scaleExp
;
}
DiyFp
rounded
(
v
.
f
>>
precisionSize
,
v
.
e
+
precisionSize
);
const
uint64_t
precisionBits
=
(
v
.
f
&
((
uint64_t
(
1
)
<<
precisionSize
)
-
1
))
*
kUlp
;
const
uint64_t
halfWay
=
(
uint64_t
(
1
)
<<
(
precisionSize
-
1
))
*
kUlp
;
DiyFp
rounded
(
v
.
f
>>
precisionSize
,
v
.
e
+
precisionSize
);
if
(
precisionBits
>=
halfWay
+
error
)
rounded
.
f
++
;
...
...
test/unittest/readertest.cpp
View file @
40852f4d
...
...
@@ -195,7 +195,6 @@ static void TestParseDouble() {
EXPECT_DOUBLE_EQ
(
x
,
h
.
actual_
);
\
}
#if 0
TEST_DOUBLE
(
fullPrecision
,
"0.0"
,
0.0
);
TEST_DOUBLE
(
fullPrecision
,
"1.0"
,
1.0
);
TEST_DOUBLE
(
fullPrecision
,
"-1.0"
,
-
1.0
);
...
...
@@ -216,7 +215,6 @@ static void TestParseDouble() {
TEST_DOUBLE
(
fullPrecision
,
"2.22507e-308"
,
2.22507e-308
);
TEST_DOUBLE
(
fullPrecision
,
"-1.79769e+308"
,
-
1.79769e+308
);
TEST_DOUBLE
(
fullPrecision
,
"-2.22507e-308"
,
-
2.22507e-308
);
#endif
TEST_DOUBLE
(
fullPrecision
,
"4.9406564584124654e-324"
,
4.9406564584124654e-324
);
// minimum denormal
TEST_DOUBLE
(
fullPrecision
,
"2.2250738585072009e-308"
,
2.2250738585072009e-308
);
// Max subnormal double
TEST_DOUBLE
(
fullPrecision
,
"2.2250738585072014e-308"
,
2.2250738585072014e-308
);
// Min normal positive double
...
...
@@ -259,7 +257,7 @@ static void TestParseDouble() {
TEST_DOUBLE
(
fullPrecision
,
n1e308
,
1E308
);
}
#if
0
#if
1
static
const
unsigned
count
=
10000000
;
// Random test for double
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment