Uploaded image for project: 'Drivers'
  1. Drivers
  2. DRIVERS-952

Define stringification of floats in extended json more precisely

    • Type: Icon: Spec Change Spec Change
    • Resolution: Unresolved
    • Priority: Icon: Minor - P4 Minor - P4
    • None
    • Component/s: Extended JSON
    • None

      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>'
      

            Assignee:
            Unassigned Unassigned
            Reporter:
            oleg.pudeyev@mongodb.com Oleg Pudeyev (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated: