Skip to content

Commit c9e3f69

Browse files
committed
Faithfully represent large doubles.
1 parent d08a3ad commit c9e3f69

File tree

1 file changed

+26
-9
lines changed

1 file changed

+26
-9
lines changed

src/Dumper.cpp

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -215,17 +215,34 @@ void Dumper::appendUInt(uint64_t v) {
215215

216216
void Dumper::appendDouble(double v) {
217217
char temp[24];
218-
int len = fpconv_dtoa(v, &temp[0]);
219-
_sink->append(&temp[0], static_cast<ValueLength>(len));
220-
if (fabs(v) < ldexpl(1.0, 53)) {
221-
return;
222-
}
223-
for (size_t i = 0; i < len; ++i) {
224-
if (temp[i] == '.' || temp[i] == 'e' || temp[i] == 'E') {
225-
return;
218+
double a = fabs(v);
219+
if (a >= ldexpl(1.0, 53) && a < ldexpl(1.0, 64)) {
220+
// This is a special case which we want to handle separately, because
221+
// of two reasons:
222+
// (1) The function fpconv_dtoa below only guarantees to write a
223+
// decimal representation which gives the same double value when
224+
// parsed back into a double. It can write a wrong integer.
225+
// Therefore we want to use the integer code in this case.
226+
// (2) The function fpconv_dtoa will write a normal integer
227+
// representation in this case without a decimal point. If we
228+
// parse this back to vpack later, we end up in a different
229+
// representation (uint64_t or int64_t), so we want to append
230+
// ".0" to the string in this case.
231+
// Note that this automatically excludes all infinities and NaNs,
232+
// which will be handled in the function fpconv_dtoa below.
233+
uint64_t u;
234+
if (v < 0) {
235+
u = static_cast<uint64_t>(-v);
236+
_sink->append("-", 1);
237+
} else {
238+
u = static_cast<uint64_t>(v);
226239
}
240+
appendUInt(u);
241+
_sink->append(".0", 2);
242+
return;
227243
}
228-
_sink->append(".0", 2);
244+
int len = fpconv_dtoa(v, &temp[0]);
245+
_sink->append(&temp[0], static_cast<ValueLength>(len));
229246
}
230247

231248
void Dumper::dumpUnicodeCharacter(uint16_t value) {

0 commit comments

Comments
 (0)