Precise numbers in JSON get parsed as Floats #6114

Closed
davout opened this Issue May 2, 2012 · 8 comments

Comments

Projects
None yet
4 participants
Contributor

davout commented May 2, 2012

json_string = '{ "my_number" : 0.00000001 }'
JSON.parse(json_string)['my_number'].class
=> Float

IMHO everything should either get parsed as Fixnum/Bignumif integer, or BigDecimal if not.
This way, we never lose precision and may convert back to Float, if and only if desired.

You example is probably using the JSON gem, which can be found here. I think you can ask for feedback about your possible issue in json repository / issues tracker, given it's not Rails the one that actually does the parsing. Thanks!

Contributor

davout commented May 2, 2012

This also happens when Rails parses a JSON request body.
The fix could be to patch the JSON gem, but it could also be to bump its version or replace it altogether with another implementation.

I don't mind providing tests and code to fix this, whether it's on Rails or one of its dependencies doesn't matter, but this issue should remain open until the behaviour is fixed.

Rails internals only use ActiveSupport::JSON - as you can see in params parser, that is basically a wrapper for MultiJson. Rails is not parsing anything "by hand" in the json side, this is provided by other implementations.

As an example Yajl, will give you the same results:

>> parser = Yajl::Parser.new
=> #<Yajl::Parser:0x007fb6b8a7b9f0>
>> json_string = '{ "my_number" : 0.00000001 }'
=> "{ \"my_number\" : 0.00000001 }"
>> s = parser.parse(json_string)
=> {"my_number"=>1.0e-08}
>> s['my_number'].class
=> Float

I don't think it's a particular Rails issue (and also issues can get stale quite fast), that's why I closed it. I'll gladly reopen if it ends up being considered a Rails issue, for sure. Meanwhile I'm going to ask for more feedback from the core team. Thanks for your report.

Member

steveklabnik commented May 2, 2012

There are a bunch of issues this might be a duplicate of, actually, but I forget which ones...

Contributor

davout commented May 2, 2012

@steveklabnik You might've seen issues related to BigDecimal JSON serialization, but I don't think there are any issues opened regarding JSON deserialization.

Contributor

davout commented May 2, 2012

See : brianmario/yajl-ruby#101

This should get reopened, because even if one, or more implementations are patched there's probably going to have to be some sort of configuration option at the Rails level (unless every single parser implementation used by Rails switches to bigdecimals-everywhere, which is higly doubtful).

Member

wycats commented May 2, 2012

Are you saying that fixing up (potentially) broken deserialization in third-party libraries is a Rails problem? If so, that sounds extremely scary to me.

Contributor

davout commented May 2, 2012

Let me rephrase : I'm saying that being aware that parser X is BigDecimal enabled and that parser Y isn't is a Rails issue if, as a Rails developer, I wish to have numbers deserialized in an non-approximative format.

Do you think that Rails should provide developers with the option to use a parser that is able to deserialize to non-lossy format if at least one them is capable of it? I think it should.

But if as a developer I'm easily able to force a JSON parser (application-wide) without resorting to hacking a monkey-patch then I'm perfectly happy with that.

@apneadiving apneadiving referenced this issue in apneadiving/Google-Maps-for-Rails Nov 4, 2012

Closed

Map shown is off by few miles #170

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment