Mercurial > octave
changeset 33200:9f97974976cd
Allow integer inputs greater than 999999 to jsonencode (bug #65447)
* NEWS.10.md: Announce that integers and flints are now output without ".0" suffix.
* jsonencode.cc (encode_numeric): Remove test for floating point integers being below
999999 in order to write out as integer. Add new "else if" block to process integer
inputs and write them as integers.
* jsonencode.cc (encode): Better comments for if/else if tree decoding input type.
* jsonencode_BIST.tst: New tests for integer inputs and for flints greater than 1e6.
author | Rik <rik@octave.org> |
---|---|
date | Tue, 12 Mar 2024 21:47:48 -0700 |
parents | 297fd823a953 |
children | cab636a9c37b |
files | etc/NEWS.10.md libinterp/corefcn/jsonencode.cc test/json/jsonencode_BIST.tst |
diffstat | 3 files changed, 31 insertions(+), 8 deletions(-) [+] |
line wrap: on
line diff
--- a/etc/NEWS.10.md Tue Mar 12 14:27:13 2024 -0700 +++ b/etc/NEWS.10.md Tue Mar 12 21:47:48 2024 -0700 @@ -22,6 +22,9 @@ The function no longer accepts complex inputs and will emit an error for these inputs. +- `jsonencode` now outputs integers and floating point integers without ".0" + suffix. + ### Graphical User Interface ### Graphics backend
--- a/libinterp/corefcn/jsonencode.cc Tue Mar 12 14:27:13 2024 -0700 +++ b/libinterp/corefcn/jsonencode.cc Tue Mar 12 21:47:48 2024 -0700 @@ -65,13 +65,13 @@ { double value = obj.scalar_value (); - // Any numeric input from the interpreter will be in double type so in - // order to detect ints, we will check if the floor of the input and the - // input are equal using fabs (A - B) < epsilon method as it is more - // accurate. If value > 999999, MATLAB will encode it in scientific - // notation (double). - if (fabs (floor (value) - value) < std::numeric_limits<double>::epsilon () - && fabs (value) <= 999999) + // Detect floating point numbers which are actually integers by checking + // whether the number and the integer portion of the number are the same + // to within eps. + // FIXME: If value > 999999, MATLAB will encode it in scientific + // notation, but rapidJSON will output all digits. + if (fabs (trunc (value) - value) < std::numeric_limits<double>::epsilon ()) + writer.Int64 (value); // Possibly write NULL for non-finite values (-Inf, Inf, NaN, NA) else if (ConvertInfAndNaN && ! octave::math::isfinite (value)) @@ -79,6 +79,21 @@ else writer.Double (value); } + else if (obj.isinteger ()) + { + if (obj.is_uint64_type ()) + { + uint64_t value = obj.uint64_value (); + writer.Uint64 (value); + } + else + { + // Write all other integers as 64-bit values and let RapidJSON + // determine number of digits to keep. + int64_t value = obj.int64_value (); + writer.Int64 (value); + } + } else if (obj.is_bool_scalar ()) writer.Bool (obj.bool_value ()); else @@ -404,9 +419,10 @@ encode (T& writer, const octave_value& obj, const bool& ConvertInfAndNaN) { if (obj.is_real_scalar ()) + // Numeric scalars. encode_numeric (writer, obj, ConvertInfAndNaN); - // As I checked for scalars, this will detect numeric & logical arrays else if (obj.isnumeric () || obj.islogical ()) + // Numeric and logical arrays. encode_array (writer, obj, ConvertInfAndNaN, obj.dims ()); else if (obj.is_string ()) encode_string (writer, obj, obj.dims ());
--- a/test/json/jsonencode_BIST.tst Tue Mar 12 14:27:13 2024 -0700 +++ b/test/json/jsonencode_BIST.tst Tue Mar 12 21:47:48 2024 -0700 @@ -17,6 +17,8 @@ %! assert (isequal (jsonencode (50.025), '50.025')); %! %% FIXME: Uncomment when bug #64960 is fixed %! %% assert (isequal (jsonencode (single (50.025)), '50.025')); +%! assert (isequal (jsonencode (uint64 (1e6)), '1000000')); +%! assert (isequal (jsonencode (int64 (-1e6)), '-1000000')); %! assert (isequal (jsonencode (NaN), 'null')); %! assert (isequal (jsonencode (NA), 'null')); % Octave-only test %! assert (isequal (jsonencode (Inf), 'null')); @@ -112,6 +114,8 @@ %!testif HAVE_RAPIDJSON %! assert (isequal (jsonencode ([]), '[]')); %! assert (isequal (jsonencode ([1, 2, 3, 4]), '[1,2,3,4]')); +%! % Matlab encodes flints with values above 1e6-1 in scientific notation. Octave writes integers. +%! assert (isequal (jsonencode ([1.23e6, 2]), '[1230000,2]')); %! assert (isequal (jsonencode ([true; false; true]), '[true,false,true]')); %% Test arrays