diff options
-rw-r--r-- | qobject/qnum.c | 24 | ||||
-rw-r--r-- | tests/check-qjson.c | 8 | ||||
-rw-r--r-- | tests/check-qnum.c | 4 |
3 files changed, 9 insertions, 27 deletions
diff --git a/qobject/qnum.c b/qobject/qnum.c index 7012fc57f2..bf1240ecec 100644 --- a/qobject/qnum.c +++ b/qobject/qnum.c @@ -161,37 +161,19 @@ double qnum_get_double(QNum *qn) char *qnum_to_string(QNum *qn) { - char *buffer; - int len; - switch (qn->kind) { case QNUM_I64: return g_strdup_printf("%" PRId64, qn->u.i64); case QNUM_U64: return g_strdup_printf("%" PRIu64, qn->u.u64); case QNUM_DOUBLE: - /* FIXME: snprintf() is locale dependent; but JSON requires + /* FIXME: g_strdup_printf() is locale dependent; but JSON requires * numbers to be formatted as if in the C locale. Dependence * on C locale is a pervasive issue in QEMU. */ /* FIXME: This risks printing Inf or NaN, which are not valid * JSON values. */ - /* FIXME: the default precision of 6 for %f often causes - * rounding errors; we should be using DBL_DECIMAL_DIG (17), - * and only rounding to a shorter number if the result would - * still produce the same floating point value. */ - buffer = g_strdup_printf("%f" , qn->u.dbl); - len = strlen(buffer); - while (len > 0 && buffer[len - 1] == '0') { - len--; - } - - if (len && buffer[len - 1] == '.') { - buffer[len - 1] = 0; - } else { - buffer[len] = 0; - } - - return buffer; + /* 17 digits suffice for IEEE double */ + return g_strdup_printf("%.17g", qn->u.dbl); } assert(0); diff --git a/tests/check-qjson.c b/tests/check-qjson.c index 98515b1fd6..ca8fb816e9 100644 --- a/tests/check-qjson.c +++ b/tests/check-qjson.c @@ -882,10 +882,10 @@ static void float_number(void) } test_cases[] = { { "32.43", 32.43 }, { "0.222", 0.222 }, - { "-32.12313", -32.12313 }, - { "-32.20e-10", -32.20e-10, "-0" /* BUG */ }, - { "18446744073709551616", 0x1p64 }, - { "-9223372036854775809", -0x1p63, "-9223372036854775808" }, + { "-32.12313", -32.12313, "-32.123130000000003" }, + { "-32.20e-10", -32.20e-10, "-3.22e-09" }, + { "18446744073709551616", 0x1p64, "1.8446744073709552e+19" }, + { "-9223372036854775809", -0x1p63, "-9.2233720368547758e+18" }, {}, }; int i; diff --git a/tests/check-qnum.c b/tests/check-qnum.c index a73809d021..b85fca2302 100644 --- a/tests/check-qnum.c +++ b/tests/check-qnum.c @@ -147,13 +147,13 @@ static void qnum_to_string_test(void) qn = qnum_from_double(0.42); tmp = qnum_to_string(qn); - g_assert_cmpstr(tmp, ==, "0.42"); + g_assert_cmpstr(tmp, ==, "0.41999999999999998"); g_free(tmp); qobject_unref(qn); qn = qnum_from_double(2.718281828459045); tmp = qnum_to_string(qn); - g_assert_cmpstr(tmp, ==, "2.718282"); /* BUG */ + g_assert_cmpstr(tmp, ==, "2.7182818284590451"); g_free(tmp); qobject_unref(qn); } |