You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The current implementation of JSONObject/JSONArray will store most floating point numbers as double when parsing a JSON text. For example:
{ "myFloat" : 1.234 }
Will parse into a JSONObject with a key of "myFloat" having a value of Double.valueOf("1.234"). When directly outputting this new JSONObject, no inconsistencies are noted as the Double.toString automatically performs some magic rounding to get us the same string representation of "1.234".
However, the same can't be said of conversion to BigDecimal. Using the same JSON text/JSONObject above, a subsequent call to getBigDecimal("myFloat") will instead return a BigDecimal with a value of 1.2339999675750732421875. The main reason for using this type of conversion is to preserve any possible value that may have happened due to a purposeful calculation as opposed to assuming the value should be 1.234. For example: JSONObject.put("myKey",someDouble+1.234f); Where the value is purposefully set to a double value.
The goal of this issue is not to change the conversion from double->BigDecimal, but instead to change how we interpret the textual numbers upon parsing.
Numbers in the JSON specifications are always noted in decimal form; i.e. Hex, octal, and binary numbers are not allowed in the formal specification. Java however, uses binary notation for it's floating point numbers float and double (see ieee 754). This causes an inconsistency between what is presented in the original data, and what we parse and store in the backend of JSONObject and JSONArray.
By changing the parser to always use BigDecimal, the backing data will better match the file data that is parsed. The get/opt methods themselves would return a different implementation type, but the get/optDouble methods would still return the proper values. Given how the raw get/opt methods work, I don't think this is a large issue as it would currently return any of 6 Number types (BigDecimal, BigInteger, Double, Float, Long, or Integer) if the value is a number (it changes based on number format and size).
The text was updated successfully, but these errors were encountered:
The current implementation of JSONObject/JSONArray will store most floating point numbers as double when parsing a JSON text. For example:
Will parse into a JSONObject with a key of "myFloat" having a value of
Double.valueOf("1.234")
. When directly outputting this new JSONObject, no inconsistencies are noted as theDouble.toString
automatically performs some magic rounding to get us the same string representation of "1.234".However, the same can't be said of conversion to BigDecimal. Using the same JSON text/JSONObject above, a subsequent call to
getBigDecimal("myFloat")
will instead return a BigDecimal with a value of1.2339999675750732421875
. The main reason for using this type of conversion is to preserve any possible value that may have happened due to a purposeful calculation as opposed to assuming the value should be 1.234. For example:JSONObject.put("myKey",someDouble+1.234f);
Where the value is purposefully set to a double value.The goal of this issue is not to change the conversion from
double
->BigDecimal
, but instead to change how we interpret the textual numbers upon parsing.Numbers in the JSON specifications are always noted in decimal form; i.e. Hex, octal, and binary numbers are not allowed in the formal specification. Java however, uses binary notation for it's floating point numbers
float
anddouble
(see ieee 754). This causes an inconsistency between what is presented in the original data, and what we parse and store in the backend of JSONObject and JSONArray.By changing the parser to always use BigDecimal, the backing data will better match the file data that is parsed. The get/opt methods themselves would return a different implementation type, but the get/optDouble methods would still return the proper values. Given how the raw get/opt methods work, I don't think this is a large issue as it would currently return any of 6 Number types (BigDecimal, BigInteger, Double, Float, Long, or Integer) if the value is a number (it changes based on number format and size).
The text was updated successfully, but these errors were encountered: