Skip to content

Commit

Permalink
correct error in converting doubles to big decimals
Browse files Browse the repository at this point in the history
  • Loading branch information
johnjaylward committed Jul 23, 2021
1 parent c03054b commit 7cfa2c0
Show file tree
Hide file tree
Showing 3 changed files with 12 additions and 8 deletions.
4 changes: 2 additions & 2 deletions src/main/java/org/json/JSONArray.java
Expand Up @@ -385,7 +385,7 @@ public <E extends Enum<E>> E getEnum(Class<E> clazz, int index) throws JSONExcep

/**
* Get the BigDecimal value associated with an index. If the value is float
* or double, the the {@link BigDecimal#BigDecimal(double)} constructor
* or double, the the {@link BigDecimal#BigDecimal(String)} constructor
* will be used. See notes on the constructor for conversion issues that
* may arise.
*
Expand Down Expand Up @@ -792,7 +792,7 @@ public BigInteger optBigInteger(int index, BigInteger defaultValue) {
* Get the optional BigDecimal value associated with an index. The
* defaultValue is returned if there is no value for the index, or if the
* value is not a number and cannot be converted to a number. If the value
* is float or double, the the {@link BigDecimal#BigDecimal(double)}
* is float or double, the the {@link BigDecimal#BigDecimal(String)}
* constructor will be used. See notes on the constructor for conversion
* issues that may arise.
*
Expand Down
9 changes: 6 additions & 3 deletions src/main/java/org/json/JSONObject.java
Expand Up @@ -644,7 +644,7 @@ public BigInteger getBigInteger(String key) throws JSONException {

/**
* Get the BigDecimal value associated with a key. If the value is float or
* double, the the {@link BigDecimal#BigDecimal(double)} constructor will
* double, the the {@link BigDecimal#BigDecimal(String)} constructor will
* be used. See notes on the constructor for conversion issues that may
* arise.
*
Expand Down Expand Up @@ -1137,7 +1137,7 @@ public boolean optBoolean(String key, boolean defaultValue) {
* Get an optional BigDecimal associated with a key, or the defaultValue if
* there is no such key or if its value is not a number. If the value is a
* string, an attempt will be made to evaluate it as a number. If the value
* is float or double, then the {@link BigDecimal#BigDecimal(double)}
* is float or double, then the {@link BigDecimal#BigDecimal(String)}
* constructor will be used. See notes on the constructor for conversion
* issues that may arise.
*
Expand Down Expand Up @@ -1172,7 +1172,10 @@ static BigDecimal objectToBigDecimal(Object val, BigDecimal defaultValue) {
if (!numberIsFinite((Number)val)) {
return defaultValue;
}
return new BigDecimal(((Number) val).doubleValue());
// use the string constructor so that we maintain "nice" values for doubles and floats
// the double constructor will translate doubles to "exact" values instead of the likely
// intended representation
return new BigDecimal(val.toString());
}
if (val instanceof Long || val instanceof Integer
|| val instanceof Short || val instanceof Byte){
Expand Down
7 changes: 4 additions & 3 deletions src/test/java/org/json/junit/JSONObjectTest.java
Expand Up @@ -126,6 +126,7 @@ public void verifySimilar() {

assertTrue("Should eval to true", obj1.similar(obj4));

// verify that a double and big decimal are "similar"
assertTrue("should eval to true",new JSONObject().put("a",1.1d).similar(new JSONObject("{\"a\":1.1}")));

}
Expand Down Expand Up @@ -942,7 +943,7 @@ public void stringToValueNumbersTest() {
assertTrue("-0 Should be a Double!",JSONObject.stringToValue("-0") instanceof Double);
assertTrue("-0.0 Should be a Double!",JSONObject.stringToValue("-0.0") instanceof Double);
assertTrue("'-' Should be a String!",JSONObject.stringToValue("-") instanceof String);
assertTrue( "0.2 should be a Double!",
assertTrue( "0.2 should be a BigDecimal!",
JSONObject.stringToValue( "0.2" ) instanceof BigDecimal );
assertTrue( "Doubles should be BigDecimal, even when incorrectly converting floats!",
JSONObject.stringToValue( new Double( "0.2f" ).toString() ) instanceof BigDecimal );
Expand Down Expand Up @@ -2521,8 +2522,8 @@ public void jsonObjectOptBigDecimal() {

assertEquals(new BigDecimal("123"),jo.optBigDecimal("int", null));
assertEquals(new BigDecimal("654"),jo.optBigDecimal("long", null));
assertEquals(new BigDecimal(1.234f),jo.optBigDecimal("float", null));
assertEquals(new BigDecimal(2.345d),jo.optBigDecimal("double", null));
assertEquals(new BigDecimal("1.234"),jo.optBigDecimal("float", null));
assertEquals(new BigDecimal("2.345"),jo.optBigDecimal("double", null));
assertEquals(new BigDecimal("1234"),jo.optBigDecimal("bigInteger", null));
assertEquals(new BigDecimal("1234.56789"),jo.optBigDecimal("bigDecimal", null));
assertNull(jo.optBigDecimal("nullVal", null));
Expand Down

0 comments on commit 7cfa2c0

Please sign in to comment.