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 /src | |
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.
Diffstat (limited to 'src')
-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); } |