How to prevent JSONObject from json.jar converts decimal numbers string into double
Unrelated to the JSON library you use, you should not use the BigDecimal constructor taking a double parameter, since that uses the exact decimal representation of the double's binary floating-point value
Instead, use the static valueOf
method since that uses the string value of the double and thus rounds correctly.
When a double must be used as a source for a BigDecimal, note that this constructor provides an exact conversion; it does not give the same result as converting the double to a String using the
Double.toString(double)
method and then using theBigDecimal(String)
constructor. To get that result, use the staticvalueOf(double)
method.
However, for very large or small numbers the parsing to a double might already have introduced rounding errors, in that case the only solution would be to use a different JSON library that supports parsing numbers as BigDecimals.
In org.json.JSONObject class comment out lines in method stringToValue(String string)
/* * If it might be a number, try converting it. If a number cannot be * produced, then the value will just be a string. */ char initial = string.charAt(0); if ((initial >= '0' && initial <= '9') || initial == '-') { try { // if we want full Big Number support this block can be replaced with: // return stringToNumber(string); if (isDecimalNotation(string)) { Double d = Double.valueOf(string); if (!d.isInfinite() && !d.isNaN()) { return d; } } else { Long myLong = Long.valueOf(string); if (string.equals(myLong.toString())) { if (myLong.longValue() == myLong.intValue()) { return Integer.valueOf(myLong.intValue()); } return myLong; } } } catch (Exception ignore) { } }