Skip to content

Commit fa5bdf8

Browse files
committed
Adjust fpconv to add ".0" to integers
Adds a test case fix
1 parent 7d77415 commit fa5bdf8

File tree

3 files changed

+19
-13
lines changed

3 files changed

+19
-13
lines changed

ext/json/ext/generator/generator.c

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1084,18 +1084,9 @@ static void generate_json_float(FBuffer *buffer, struct generate_json_data *data
10841084
char* d = buffer->ptr + buffer->len;
10851085
int len = fpconv_dtoa(value, d);
10861086

1087-
/* fpconv_dtoa converts a float to its shorted string representation. When
1088-
* converting a float that is exactly an integer (e.g. `Float(2)`) this
1089-
* returns in a string that looks like an integer. This is correct, since
1090-
* JSON treats ints and floats the same. However, to not break integrations
1091-
* that expect a string representation looking like a float, we append a
1092-
* "." in that case.
1087+
/* fpconv_dtoa converts a float to its shortest string representation,
1088+
* but it adds a ".0" if this is a plain integer.
10931089
*/
1094-
if(!memchr(d, '.', len) && !memchr(d, 'e', len)) {
1095-
d[len] = '.';
1096-
d[len+1] = '0';
1097-
len += 2;
1098-
}
10991090
buffer->len += len;
11001091
}
11011092

ext/json/ext/vendor/fpconv/src/fpconv.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,11 @@ static int emit_digits(char* digits, int ndigits, char* dest, int K, bool neg)
222222
memcpy(dest, digits, ndigits);
223223
memset(dest + ndigits, '0', K);
224224

225-
return ndigits + K;
225+
/* add a .0 to mark this as a float. */
226+
dest[ndigits + K] = '.';
227+
dest[ndigits + K + 1] = '0';
228+
229+
return ndigits + K + 2;
226230
}
227231

228232
/* write decimal w/o scientific notation */
@@ -290,7 +294,9 @@ static int filter_special(double fp, char* dest)
290294
{
291295
if(fp == 0.0) {
292296
dest[0] = '0';
293-
return 1;
297+
dest[1] = '.';
298+
dest[2] = '0';
299+
return 3;
294300
}
295301

296302
uint64_t bits = get_dbits(fp);

test/json/json_generator_test.rb

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -698,4 +698,13 @@ def test_json_generate_as_json_convert_to_proc
698698
object = Object.new
699699
assert_equal object.object_id.to_json, JSON.generate(object, strict: true, as_json: :object_id)
700700
end
701+
702+
def test_json_generate_float
703+
values = [-1.0, 1.0, 0.0, 12.2, 7.5 / 3.2, 12.0, 100.0, 1000.0]
704+
expecteds = ["-1.0", "1.0", "0.0", "12.2", "2.34375", "12.0", "100.0", "1000.0"]
705+
706+
values.zip(expecteds).each do |value, expected|
707+
assert_equal expected, value.to_json
708+
end
709+
end
701710
end

0 commit comments

Comments
 (0)