[DRIVERS-952] Define stringification of floats in extended json more precisely Created: 09/Jan/20  Updated: 31/Mar/22

Status: Backlog
Project: Drivers
Component/s: Extended JSON
Fix Version/s: None

Type: Spec Change Priority: Minor - P4
Reporter: Oleg Pudeyev (Inactive) Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Related
related to RUBY-2066 Extended json serialization Closed

 Description   

MRI Ruby and JRuby differ in how they stringify large floats.

MRI:

irb(main):014:0> 1e15.to_s
=> "1.0e+15"

JRuby:

irb(main):001:0> 1e15.to_s
=> "1000000000000000.0"

1e14 in both interpreters stringifies the same:

irb(main):003:0> 1e14.to_s
=> "100000000000000.0"

The spec tests implicitly require that there is a single stringification of floats done by all implementations, as the following test fails on JRuby:

 
  2) BSON Corpus spec tests (double.json): Double type valid: -1.2345678901234568e+18 - precision adjusted for Ruby converts bson to canonical extended json
     Failure/Error: decoded_canonical_bson.as_extended_json.should == test.canonical_extjson_doc
     
       expected: {"d"=>{"$numberDouble"=>"-1.2345678901234568e+18"}}
            got: {"d"=>{"$numberDouble"=>"-1234567890123456770.0"}} (using ==)
       Diff:
       @@ -1,2 +1,2 @@
       -"d" => {"$numberDouble"=>"-1.2345678901234568e+18"},
       +"d" => {"$numberDouble"=>"-1234567890123456770.0"},
       
     # ./spec/spec_tests/corpus_spec.rb:35:in `block in <main>'

The extended json spec has the following language regarding float stringification:

>

{"$numberDouble": <64-bit signed floating point as a decimal string>}

This language does not mandate a particular representation.

When I changed Ruby extended json serializer to use %g format, a number of other tests failed that expect zero floats to be serialized to "0.0" rather than "0". Example:

  7) BSON Corpus spec tests (double.json): Double type valid: 0.0 converts bson to canonical extended json
     Failure/Error: decoded_canonical_bson.as_extended_json.should == test.canonical_extjson_doc
     
       expected: {"d"=>{"$numberDouble"=>"0.0"}}
            got: {"d"=>{"$numberDouble"=>"0"}} (using ==)
       Diff:
       @@ -1,2 +1,2 @@
       -"d" => {"$numberDouble"=>"0.0"},
       +"d" => {"$numberDouble"=>"0"},
       
     # ./spec/spec_tests/corpus_spec.rb:35:in `block in <main>'
 
                                                                                
  8) BSON Corpus spec tests (double.json): Double type valid: -0.0 converts bson to canonical extended json
     Failure/Error: decoded_canonical_bson.as_extended_json.should == test.canonical_extjson_doc
     
       expected: {"d"=>{"$numberDouble"=>"-0.0"}}
            got: {"d"=>{"$numberDouble"=>"-0"}} (using ==)
       Diff:
       @@ -1,2 +1,2 @@
       -"d" => {"$numberDouble"=>"-0.0"},
       +"d" => {"$numberDouble"=>"-0"},
       
     # ./spec/spec_tests/corpus_spec.rb:35:in `block in <main>'


Generated at Thu Feb 08 08:22:39 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.