-
Notifications
You must be signed in to change notification settings - Fork 2.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Large numbers parsed as strings #497
Comments
@slisaasquatch Thanks for bringing up this issue; interesting that numbers are handled differently depending on whether chars like '.' or 'e' are present. Do you want to present a case that the code is not in compliance with ECMA-404 and/or RFC8259? Otherwise, I believe this behavior has been in the code since the first commit for this repo (see stringToValue()). |
I was pretty sure we changed this behavior a few years ago to use BigInteger instead for these cases. Let me try with a recent build |
Ah, we never made the full switch. I left notes in the code on where it would be handled though: https://github.com/stleary/JSON-java/blob/master/JSONObject.java#L2173-L2218 |
I think that code review is still open, if you mean #453, due to changes to existing behavior. |
Thanks for your quick response. I checked the specs for numbers here, and all it says about really large numbers is that implementations may approximate the numbers to fit double precision floating points, and says nothing about turning large number into strings. And in this case, the number actually does fit into a double precision floating point. |
@stleary, yes. that PR would fix this and open up the parser to have more exact representation of what was in the original JSON text. |
My best guess is that this implementation only guarantees integer interoperability to 2 ** 53 per the spec via Java Long type, and Double was only used to support decimal and scientific notation. I think if you have access to the software that generates very large numbers, it is probably better to just serialize them as strings. |
@johnjaylward Agreed, exact representation is preferred. I wanted to keep the PR open to see if there is a way to implement it as an option, to ensure existing applications don't break. |
@stleary, gotcha. If I have time, I'll see if I can come up with a "parser config" type object that could be used to configure how items are parsed. @slisaasquatch as a work around for your specific example, you can represent the number with a decimal point, or use scientific notation to force the parser to try to use a double as the backing type instead of an integer. @Test
public void testLargeNum() {
final JSONObject j = new JSONObject("{\r\n" +
" \"foo\": 10000000000000000000000000000000.0\r\n" +
"}");
// The following line prints class Double!!!
System.out.println(j.get("foo").getClass());
} OR: @Test
public void testLargeNum() {
final JSONObject j = new JSONObject("{\r\n" +
" \"foo\": 1e31\r\n" +
"}");
// The following line prints class Double!!!
System.out.println(j.get("foo").getClass());
} |
@Test
public void testLargeNum() {
final JSONObject j = new JSONObject("{\r\n" +
" \"foo\": 10000000000000000000000000000000\r\n" +
"}");
// The following line prints class java.lang.String!!!
System.out.println(j.get("foo").getClass());
} The expected value is |
@javadev yes. This has been a known limitation of the library for quite some time. When a number can not be parsed as an integer or a double, it stores it as a string internally. In our case, we only parse using a In cases where the caller requires a number, this can be worked around by using the According to the JSON specifications, a parser has no obligation to handle values that don't fit in 64-bit integer or floating point data type ( |
Closed due to working as designed. |
Here's the sample code:
The text was updated successfully, but these errors were encountered: