diff options
author | Petri Lehtinen <petri@digip.org> | 2009-12-17 23:42:13 +0200 |
---|---|---|
committer | Petri Lehtinen <petri@digip.org> | 2009-12-18 00:05:06 +0200 |
commit | ec96cbf01693a90db15a13c3e77f68909036989e (patch) | |
tree | d697085af6755c905cf664ff84176ed115e5c96e | |
parent | 7c707a73a2251c20afaecc028267b99d0ee60184 (diff) | |
download | jansson-ec96cbf01693a90db15a13c3e77f68909036989e.zip jansson-ec96cbf01693a90db15a13c3e77f68909036989e.tar.gz jansson-ec96cbf01693a90db15a13c3e77f68909036989e.tar.bz2 |
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.
-rw-r--r-- | src/dump.c | 17 |
1 files changed, 16 insertions, 1 deletions
@@ -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); } |