From 7f4196213a88ee8a51768efae9232a0e559d5fb9 Mon Sep 17 00:00:00 2001 From: Javid Khan Date: Mon, 26 Oct 2026 22:07:35 +0530 Subject: [PATCH] keep the exponent when trimming zeroes with JSON_C_TO_STRING_NOZERO --- json_object.c | 13 ++++++++----- tests/test_double_serializer.c | 12 ++++++++++++ tests/test_double_serializer.expected | 2 ++ 3 files changed, 22 insertions(+), 5 deletions(-) diff --git a/json_object.c b/json_object.c index 9343c00..a36bf52 100644 --- a/json_object.c +++ b/json_object.c @@ -1328,15 +1328,18 @@ static int json_object_double_to_json_string_format(struct json_object *jso, str { /* last useful digit, always keep 1 zero */ p++; - for (q = p; *q; q++) + for (q = p; is_plain_digit(*q); q++) { if (*q != '0') p = q; } - /* drop trailing zeroes */ - if (*p != 0) - *(++p) = 0; - size = p - buf; + /* drop trailing zeroes, keeping any exponent after them */ + if (is_plain_digit(*p)) + { + p++; + memmove(p, q, strlen(q) + 1); + } + size = (int)strlen(buf); } } // although unlikely, snprintf can fail diff --git a/tests/test_double_serializer.c b/tests/test_double_serializer.c index 59e95c2..e0299ba 100644 --- a/tests/test_double_serializer.c +++ b/tests/test_double_serializer.c @@ -41,6 +41,18 @@ int main(int argc, char **argv) json_object_set_serializer(obj, json_object_double_to_json_string, data, NULL); printf("obj.to_string(reset)=%s\n", json_object_to_json_string_ext(obj, 4)); + json_object_put(obj); + /* NOZERO must only trim the fraction, never the exponent */ + obj = json_object_new_double(1.5e20); + printf("obj(1.5e20).to_string(nozero)=%s\n", + json_object_to_json_string_ext(obj, JSON_C_TO_STRING_NOZERO)); + json_object_put(obj); + obj = json_object_new_double(1.5e20); + char data_e[] = "%.3e"; + json_object_set_serializer(obj, json_object_double_to_json_string, data_e, NULL); + printf("obj(1.5e20).to_string(%%.3e,nozero)=%s\n", + json_object_to_json_string_ext(obj, JSON_C_TO_STRING_NOZERO)); + json_object_put(obj); obj = json_object_new_double(0.52381); diff --git a/tests/test_double_serializer.expected b/tests/test_double_serializer.expected index 8e3b7e4..76496ef 100644 --- a/tests/test_double_serializer.expected +++ b/tests/test_double_serializer.expected @@ -8,6 +8,8 @@ Test reset serializer: obj.to_string(reset)=0.5 Test no zero reset serializer: obj.to_string(reset)=3.1415000000000002 +obj(1.5e20).to_string(nozero)=1.5e+20 +obj(1.5e20).to_string(%.3e,nozero)=1.5e+20 obj.to_string(default format)=0.52381 obj.to_string(with global format)=x0.524y obj.to_string(with thread format)=T0.52X