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

JSONObject.objectToBigDecimal precision errors when parsing doubles #531

Closed
Bohlski opened this issue Jun 23, 2020 · 6 comments · Fixed by #532
Closed

JSONObject.objectToBigDecimal precision errors when parsing doubles #531

Bohlski opened this issue Jun 23, 2020 · 6 comments · Fixed by #532

Comments

@Bohlski
Copy link

Bohlski commented Jun 23, 2020

When parsing doubles the method uses the BigDecimal(double) constructor, which can have unpredictable results as stated in the docs: https://docs.oracle.com/javase/7/docs/api/java/math/BigDecimal.html#BigDecimal(double)

It is instead preferred to use BigDecimal.valueOf(double)
https://docs.oracle.com/javase/7/docs/api/java/math/BigDecimal.html#valueOf(double)

This lead to a few precision errors on my end, when updating from an older version of this library.

@johnjaylward
Copy link
Contributor

@Bohlski which version of the library is currently giving you the issue, the master branch or the latest release on Maven?

@Bohlski
Copy link
Author

Bohlski commented Jun 24, 2020

@johnjaylward The latest release on Maven

@johnjaylward
Copy link
Contributor

johnjaylward commented Jun 24, 2020 via email

@Bohlski
Copy link
Author

Bohlski commented Jun 25, 2020

Looks to me like any use of the constructor on a decimal will give the extra unwanted precision digits.
At least any time I've tried the results have been the same.

But I guess I can give a boiled down version of my current test:

public void testObjectToBigDecimal() {  
    double value = 1412078745.01074;  
    Reader reader = new StringReader("[{\"value\": " + value + "}]");
    JSONTokener tokener = new JSONTokener(reader);
    JSONArray array = new JSONArray(tokener);
    JSONObject jsonObject = array.getJSONObject(0);

    BigDecimal current = jsonObject.getBigDecimal("value");
    BigDecimal wantedValue = BigDecimal.valueOf(value);

    Assert.assertEquals(current, wantedValue);
 }

This fails with output
Expected :1412078745.01074
Actual :1412078745.0107400417327880859375

Within the newer versions (post version 20180813, I believe), getBigDecimal calls JSONObject.objectToBigDecimal which has the unwanted behaviour.

@stleary
Copy link
Owner

stleary commented Jun 25, 2020

@Bohlski We will look into these questions:

  • Have recent commits resulted in changed behavior, causing problems for lib users?
  • When was the change introduced?
  • Should the change be reverted?
  • Should some other mitigation be provided?

johnjaylward pushed a commit to johnjaylward/JSON-java that referenced this issue Jun 25, 2020
Add test result to confirm that stleary#531 is working in latest version.
@johnjaylward
Copy link
Contributor

I used the test case provided and confirmed that the changes in latest master branch correct the issue.

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

Successfully merging a pull request may close this issue.

3 participants