Skip to content
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

Parse JSON numbers to Number type instead of Double. #1288

Closed
wants to merge 1 commit into from
Closed

Parse JSON numbers to Number type instead of Double. #1288

wants to merge 1 commit into from

Conversation

zenglian
Copy link
Contributor

@zenglian zenglian commented Apr 15, 2018

Currently all numbers are parsed as Double thus integers are parsed as "int.0", which is wrong according to JSON specification (see www.json.org). With the spec, JSON's number is defined as "int or
int.frac or scientific annotation". This fix parses JSON numbers to Java's Number using NumberFormat parser, which correctly parses JSON numbers to Long and Double respectively. This resolves a lot of issues raised in the past years and also correctly parse "9223372036854775807" to Long.MAX_VALUE without precision loss.

@zenglian
Copy link
Contributor Author

zenglian commented Apr 15, 2018

    public void testNumber() {
        Gson gson = new Gson();
        Object[] numbers1 = new Object[]{1, 1.0, 1.23, 9223372036854775807L, new BigInteger("9223372036854775808"),
                1.23E10, 1.23E20};
        String json = gson.toJson(numbers1);
        Object[] numbers2 = gson.fromJson(json, Object[].class);
        for (int i = 0; i < numbers2.length; i++) {
            System.out.println(numbers1[i] + " (" + numbers1[i].getClass().toString().substring(6)
                    + ")\t-->\t" + numbers2[i] + " (" + numbers2[i].getClass().toString().substring(6) + ")");
        }
    }

//result
1 (java.lang.Integer)	-->	1 (java.lang.Long)
1.0 (java.lang.Double)	-->	1 (java.lang.Long)
1.23 (java.lang.Double)	-->	1.23 (java.lang.Double)
9223372036854775807 (java.lang.Long)	-->	9223372036854775807 (java.lang.Long)
9223372036854775808 (java.math.BigInteger)	-->	9.223372036854776E18 (java.lang.Double)
1.23E10 (java.lang.Double)	-->	12300000000 (java.lang.Long)
1.23E20 (java.lang.Double)	-->	1.23E20 (java.lang.Double)

@zenglian
Copy link
Contributor Author

JSON does have "int" (the same as Java though there is no restriction on its size/no base8/16), see www.json.org.

...
number -> int | int frac | int exp | int frac exp
...

Currently all numbers are parsed as Double thus integers are parsed as
"int.0", which is **wrong** according to JSON specification (see
www.json.org). With the spec, JSON's number is defined as "int or
int.frac or scientific annotation". This fix parses JSON numbers to
Java's Number using NumberFormat parser, which correctly parses JSON
numbers to Long and Double respectively. This resolves a lot of issues
raised in the past years and also correctly parse "9223372036854775807"
to Long.MAX_VALUE and no precision is lost.
@astux7
Copy link

astux7 commented Dec 3, 2019

Can this PR be merge asap - it is an issue when i am trying to use json for long?

This pull request was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants