aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPetri Lehtinen <petri@digip.org>2009-12-17 23:42:13 +0200
committerPetri Lehtinen <petri@digip.org>2009-12-18 00:05:06 +0200
commitec96cbf01693a90db15a13c3e77f68909036989e (patch)
treed697085af6755c905cf664ff84176ed115e5c96e /src
parent7c707a73a2251c20afaecc028267b99d0ee60184 (diff)
downloadjansson-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.c17
1 files changed, 16 insertions, 1 deletions
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);
}