From: Petri Lehtinen Date: Thu, 17 Dec 2009 21:42:13 +0000 (+0200) Subject: Encode reals correctly X-Git-Tag: 1.0_branch~182^2~3 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=ec96cbf01693a90db15a13c3e77f68909036989e;p=profile%2Fivi%2Fjansson.git Encode reals correctly This patch changes the sprintf format from "%0.17f" to "%.17g", as the f format specifier doesn't print the exponent at all. This caused losing precision in all but the most simple cases. Because the g specifier doesn't print the decimal fraction or exponent if they're not needed, a ".0" has to be appended by hand in these cases. Otherwise the value's type changes from real to integer when decoding again. Thanks to Philip Grandinetti for reporting this issue. --- diff --git a/src/dump.c b/src/dump.c index 7dbc9f2..bd12a7b 100644 --- a/src/dump.c +++ b/src/dump.c @@ -145,10 +145,25 @@ static int do_dump(const json_t *json, unsigned long flags, int depth, char buffer[MAX_REAL_STR_LENGTH]; int size; - size = snprintf(buffer, MAX_REAL_STR_LENGTH, "%0.17f", json_real_value(json)); + size = snprintf(buffer, MAX_REAL_STR_LENGTH, "%.17g", + json_real_value(json)); if(size >= MAX_REAL_STR_LENGTH) return -1; + /* Make sure there's a dot or 'e' in the output. Otherwise + a real is converted to an integer when decoding */ + if(strchr(buffer, '.') == NULL && + strchr(buffer, 'e') == NULL) + { + if(size + 2 >= MAX_REAL_STR_LENGTH) { + /* No space to append ".0" */ + return -1; + } + buffer[size] = '.'; + buffer[size + 1] = '0'; + size += 2; + } + return dump(buffer, size, data); }