diff --git a/src/common/sstream.c b/src/common/sstream.c index aabdd6ab..3cd98d93 100644 --- a/src/common/sstream.c +++ b/src/common/sstream.c @@ -7,6 +7,8 @@ #include #include #include +#include +#include #include void c11_sbuf__ctor(c11_sbuf* self) { @@ -53,21 +55,26 @@ void c11_sbuf__write_f64(c11_sbuf* self, double val, int precision) { char b[32]; int size; if(precision < 0) { - int prec = 17 - 1; // std::numeric_limits::max_digits10 == 17 - size = snprintf(b, sizeof(b), "%.*g", prec, val); + // Pick the shortest decimal width that round-trips to the same binary double. + for(int prec = 15; prec <= 17; prec++) { + size = snprintf(b, sizeof(b), "%.*g", prec, val); + double parsed = strtod(b, NULL); + if(memcmp(&parsed, &val, sizeof(double)) == 0) break; + } + bool all_is_digit = true; + for(int i = 1; i < size; i++) { + if(!isdigit(b[i])) { + all_is_digit = false; + break; + } + } + c11_sbuf__write_cstr(self, b); + if(all_is_digit) c11_sbuf__write_cstr(self, ".0"); } else { int prec = precision; size = snprintf(b, sizeof(b), "%.*f", prec, val); + c11_sbuf__write_cstr(self, b); } - c11_sbuf__write_cstr(self, b); - bool all_is_digit = true; - for(int i = 1; i < size; i++) { - if(!isdigit(b[i])) { - all_is_digit = false; - break; - } - } - if(all_is_digit) c11_sbuf__write_cstr(self, ".0"); } void c11_sbuf__write_sv(c11_sbuf* self, c11_sv sv) { diff --git a/src/modules/json.c b/src/modules/json.c index 181d4aff..fca273f6 100644 --- a/src/modules/json.c +++ b/src/modules/json.c @@ -102,7 +102,7 @@ static bool json__write_namedict_kv(py_Name k, py_Ref v, void* ctx_) { static bool json__write_object(c11_sbuf* buf, py_TValue* obj, int indent, int depth) { switch(obj->type) { case tp_NoneType: c11_sbuf__write_cstr(buf, "null"); return true; - case tp_int: c11_sbuf__write_int(buf, obj->_i64); return true; + case tp_int: c11_sbuf__write_i64(buf, obj->_i64); return true; case tp_float: { if(dmath_isnan(obj->_f64)) { c11_sbuf__write_cstr(buf, "NaN"); diff --git a/tests/250_rfstring.py b/tests/250_rfstring.py index 5b687bd6..d2f93ed8 100644 --- a/tests/250_rfstring.py +++ b/tests/250_rfstring.py @@ -64,6 +64,7 @@ assert f'{a:010f}' == '010.000000' assert f'{a:010.2f}' == '0000010.00' assert f'{a:.2f}' == '10.00' assert f'{a:.5f}' == '10.00000' +assert f'{2.5:.0f}' == '2' b = '123' assert f'{b:10}' == '123 ' diff --git a/tests/721_json.py b/tests/721_json.py index 29d168bc..8509d02b 100644 --- a/tests/721_json.py +++ b/tests/721_json.py @@ -48,6 +48,9 @@ _j = json.dumps(c) _c = json.loads(_j) assert c == _c +assert json.dumps(9223372036854775807) == '9223372036854775807' +assert json.loads(json.dumps(0.1 + 0.2)) == 0.1 + 0.2 + d = True _j = json.dumps(d) _d = json.loads(_j)