diff options
-rw-r--r-- | ext/json/ext/vendor/fpconv/src/fpconv.c | 10 | ||||
-rw-r--r-- | ext/json/generator/generator.c | 13 | ||||
-rwxr-xr-x | test/json/json_generator_test.rb | 9 |
3 files changed, 19 insertions, 13 deletions
diff --git a/ext/json/ext/vendor/fpconv/src/fpconv.c b/ext/json/ext/vendor/fpconv/src/fpconv.c index 56ebb8944a..8ad80d9c6b 100644 --- a/ext/json/ext/vendor/fpconv/src/fpconv.c +++ b/ext/json/ext/vendor/fpconv/src/fpconv.c @@ -222,7 +222,11 @@ static int emit_digits(char* digits, int ndigits, char* dest, int K, bool neg) memcpy(dest, digits, ndigits); memset(dest + ndigits, '0', K); - return ndigits + K; + /* add a .0 to mark this as a float. */ + dest[ndigits + K] = '.'; + dest[ndigits + K + 1] = '0'; + + return ndigits + K + 2; } /* write decimal w/o scientific notation */ @@ -290,7 +294,9 @@ static int filter_special(double fp, char* dest) { if(fp == 0.0) { dest[0] = '0'; - return 1; + dest[1] = '.'; + dest[2] = '0'; + return 3; } uint64_t bits = get_dbits(fp); diff --git a/ext/json/generator/generator.c b/ext/json/generator/generator.c index 0f028fe072..6ef16ced8f 100644 --- a/ext/json/generator/generator.c +++ b/ext/json/generator/generator.c @@ -1084,18 +1084,9 @@ static void generate_json_float(FBuffer *buffer, struct generate_json_data *data char* d = buffer->ptr + buffer->len; int len = fpconv_dtoa(value, d); - /* fpconv_dtoa converts a float to its shorted string representation. When - * converting a float that is exactly an integer (e.g. `Float(2)`) this - * returns in a string that looks like an integer. This is correct, since - * JSON treats ints and floats the same. However, to not break integrations - * that expect a string representation looking like a float, we append a - * "." in that case. + /* fpconv_dtoa converts a float to its shortest string representation, + * but it adds a ".0" if this is a plain integer. */ - if(!memchr(d, '.', len) && !memchr(d, 'e', len)) { - d[len] = '.'; - d[len+1] = '0'; - len += 2; - } buffer->len += len; } diff --git a/test/json/json_generator_test.rb b/test/json/json_generator_test.rb index 4a92801fe1..bf4796a6bf 100755 --- a/test/json/json_generator_test.rb +++ b/test/json/json_generator_test.rb @@ -698,4 +698,13 @@ class JSONGeneratorTest < Test::Unit::TestCase object = Object.new assert_equal object.object_id.to_json, JSON.generate(object, strict: true, as_json: :object_id) end + + def test_json_generate_float + values = [-1.0, 1.0, 0.0, 12.2, 7.5 / 3.2, 12.0, 100.0, 1000.0] + expecteds = ["-1.0", "1.0", "0.0", "12.2", "2.34375", "12.0", "100.0", "1000.0"] + + values.zip(expecteds).each do |value, expected| + assert_equal expected, value.to_json + end + end end |