Skip to content

[json-org] fix issue with parsing big numbers #32

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

Merged
merged 1 commit into from
Apr 9, 2023

Conversation

pjfanning
Copy link
Member

  • equivalent of Fix issue with BigInteger handling #31
  • same issue with BigInt being parsed as a Double and Double cannot a number as big as 2e308 and treats it as Double.Infinity and things get worse from there

@cowtowncoder cowtowncoder added jsr-353 Issue related to JSR-353/JSONP datatype module 2.15 Intended for version 2.15.x labels Apr 9, 2023
@@ -66,7 +66,7 @@ public JSONArray deserialize(JsonParser p, DeserializationContext ctxt)
array.put(p.getNumberValue());
continue;
case VALUE_NUMBER_FLOAT:
array.put(p.getNumberValue());
array.put(p.getDecimalValue());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only now realizing that this is actually behavioral change too. Hmmh.
So even if improvement, might break code if the exposed number changes from Double to BigDecimal?
Or maybe JSONP API encapsulates so this is not the case?

Since I already merged changes for JSR-353/JSONP will merge this too, just noting that we may get bug reports for 2.15.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@pjfanning Doh. Not JSONP/JSR-353. Still, similar concerns.

But quick question: would it make sense to instead call p.getNumberValueExact()? This would at least retain exact Float/Double for binary formats? Would change it to BigDecimal for JSON and other textual formats, which is probably good overall.
WDYT?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if p.getNumberValueExact() works, then I'd be happy with that change - let me try a PR with that instead

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

b.add(name, p.getNumberValueExact()); doesn't compile
ie b.add does not support Number

I looked at the code in the json libs and they tend to use BigDecimal under the hood - so I think the risks of the jackson changes are low.

I think it is better to take the risk that someone will report an edge case than to add complicated logic using p.getNumberValueExact() and then lots of instanceof checks with casts.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ahh. Yes, I forgot the challenge wrt non-typed Number. I concur with your assessment.
Ideally we'd have more time for testing but TBH this module probably won't get all that much beta-testing compared to jackson-databind or jackson-core.

@cowtowncoder cowtowncoder merged commit 19afe2c into FasterXML:2.15 Apr 9, 2023
cowtowncoder added a commit that referenced this pull request Apr 9, 2023
@pjfanning pjfanning deleted the json-org-big-int-issue branch April 9, 2023 18:05
@dlipin
Copy link

dlipin commented Aug 4, 2023

FYI. I bumped to this PR/change as the result of our team investigations on change in behavior of JSONObject.get("field") when the actual value is double/float.

Our team hit this behavior change with 2.15.2 version uptake and we couldn't find any workaround. Do you have any suggestion?

The code:
new ObjectMapper().registerModule(new JsonOrgModule()).readValue("{"value": 0.5 }", JSONObject.class).get("value").getClass().getCanonicalName()
returns java.lang.Double on 2.13.4 and java.lang.BigDecimal on 2.15.2.

I was hoping that we can, at least, control the behavior DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS but it has no effect.

Do you still plan to change the behavior to use getNumberValueExact() so that it returns Double correctly as before?
Thank you for supporting the library!

@pjfanning
Copy link
Member Author

@dlipin can you open a a new issue and provide a reproducible test case?

@pjfanning
Copy link
Member Author

this test passes:

    public void testDouble() throws Exception
    {
        ObjectMapper mapper = new ObjectMapper();
        mapper.registerModule(new JsonOrgModule());

        JSONObject val = mapper.readValue("{\"val\":0.5}", JSONObject.class);
        assertEquals(0.5d, val.getDouble("val"));
    }

JSONObject has methods that let you choose the format that you want the number in. If you want a double, you call getDouble(String).

@pjfanning pjfanning mentioned this pull request Aug 4, 2023
@cowtowncoder
Copy link
Member

@dlipin like @pjfanning suggested, we'd really need a separate issue with reproduction. I think I understand the problem but there is always possibility of misunderstanding.

@dlipin
Copy link

dlipin commented Sep 20, 2023

Sorry for delay, I've filed a new issue:
#39

@cowtowncoder
Copy link
Member

Thank you @dlipin. As per my other note, I think we are going to go with the new behavior as it resolves an issue and there is a way to get Double value to if necessary.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
2.15 Intended for version 2.15.x jsr-353 Issue related to JSR-353/JSONP datatype module
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants