The current implementation of JSONObject.getLong(String) parses he value differently when it finds a string in the underlying map. When this occurs it calls JSONObject.getDouble(String) and then casts the result to a long. This unnecessary transition through a floating point value (double) is causing a loss of precision. Here is a test case that shows the issue (requires json-lib and junit):
import net.sf.json.JSONObject;
import org.junit.Assert;
import org.junit.Test;
public class JSONLibPrecisionTest {
@Test public void testJSONLongPrecision() { final long idealResult = 18858823439613958L; JSONObject json= JSONObject.fromObject( "{\"NUMBER_KEY\": " + idealResult + ",\"STRING_KEY\": \"" + idealResult + "\"}"); Assert.assertEquals( idealResult, json.getLong("NUMBER_KEY")); System.out.println("The value was read correctly from NUMBER_KEY"); Assert.assertEquals(idealResult, json.getLong("STRING_KEY")); System.out.println("The value was read correctly from STRING_KEY"); }
}
Here is the output when run with json-lib 2.4:
The value was read fine from NUMBER_KEY
java.lang.AssertionError:
Expected :18858823439613958
Actual :18858823439613960
at com.savagebeast.test.JSONTest.testJSONLongPrecision(JSONTest.java:19) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:78) at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:212) at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:68) at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)
Process finished with exit code 255
Values should not be transitioned through floating point when they are being parsed as integer values to avoid this loss of precision. Double runs out of bits to maintain precision at 2^53 - 1. Since longs range up to 2^63-1 (if signed) there is a large range of values that will be parsed incorrectly.
Development of this library has been moved to GitHub since 2010, please report any issues you may find at https://github.com/kordamp/json-lib/issues