mirror of
https://github.com/stleary/JSON-java.git
synced 2025-08-02 19:15:27 -04:00
#653 - optLong vs getLong inconsistencies
For exponential decimal conversion, number is not touched. Leading zeros removed from numeric number strings before converting to number.
This commit is contained in:
parent
79af389f7a
commit
1a38879c90
@ -2379,12 +2379,13 @@ public class JSONObject {
|
||||
* returns for this function are BigDecimal, Double, BigInteger, Long, and Integer.
|
||||
* When a Double is returned, it should always be a valid Double and not NaN or +-infinity.
|
||||
*
|
||||
* @param val value to convert
|
||||
* @param input value to convert
|
||||
* @return Number representation of the value.
|
||||
* @throws NumberFormatException thrown if the value is not a valid number. A public
|
||||
* caller should catch this and wrap it in a {@link JSONException} if applicable.
|
||||
*/
|
||||
protected static Number stringToNumber(final String val) throws NumberFormatException {
|
||||
protected static Number stringToNumber(final String input) throws NumberFormatException {
|
||||
String val = input;
|
||||
char initial = val.charAt(0);
|
||||
if ((initial >= '0' && initial <= '9') || initial == '-') {
|
||||
// decimal representation
|
||||
@ -2411,6 +2412,8 @@ public class JSONObject {
|
||||
}
|
||||
}
|
||||
}
|
||||
val = removeLeadingZerosOfNumber(input);
|
||||
initial = val.charAt(0);
|
||||
// block items like 00 01 etc. Java number parsers treat these as Octal.
|
||||
if(initial == '0' && val.length() > 1) {
|
||||
char at1 = val.charAt(1);
|
||||
@ -2886,4 +2889,33 @@ public class JSONObject {
|
||||
"JavaBean object contains recursively defined member variable of key " + quote(key)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* For a prospective number, remove the leading zeros
|
||||
* @param value prospective number
|
||||
* @return number without leading zeros
|
||||
*/
|
||||
private static String removeLeadingZerosOfNumber(String value){
|
||||
char[] chars = value.toCharArray();
|
||||
int leftMostUnsignedIndex = 0;
|
||||
if (chars[0] == '-'){
|
||||
leftMostUnsignedIndex = 1;
|
||||
}
|
||||
int firstNonZeroCharIndex = -1;
|
||||
for (int i=leftMostUnsignedIndex;i<value.length();i++){
|
||||
if (chars[i] != '0'){
|
||||
firstNonZeroCharIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (firstNonZeroCharIndex == -1){
|
||||
return value;
|
||||
}
|
||||
StringBuilder result = new StringBuilder();
|
||||
if (leftMostUnsignedIndex == 1){
|
||||
result.append('-');
|
||||
}
|
||||
result.append(value.substring(firstNonZeroCharIndex));
|
||||
return result.toString();
|
||||
}
|
||||
}
|
||||
|
@ -23,7 +23,10 @@ public class JSONObjectNumberTest {
|
||||
@Parameters(name = "{index}: {0}")
|
||||
public static Collection<Object[]> data() {
|
||||
return Arrays.asList(new Object[][]{
|
||||
{"{value:50}", 1},
|
||||
{"{value:0050}", 1},
|
||||
{"{value:0050.0000}", 1},
|
||||
{"{value:-0050}", -1},
|
||||
{"{value:-0050.0000}", -1},
|
||||
{"{value:50.0}", 1},
|
||||
{"{value:5e1}", 1},
|
||||
{"{value:5E1}", 1},
|
||||
@ -32,6 +35,7 @@ public class JSONObjectNumberTest {
|
||||
{"{value:-50}", -1},
|
||||
{"{value:-50.0}", -1},
|
||||
{"{value:-5e1}", -1},
|
||||
{"{value:-0005e1}", -1},
|
||||
{"{value:-5E1}", -1},
|
||||
{"{value:-5e1}", -1},
|
||||
{"{value:'-50'}", -1}
|
||||
|
@ -1063,12 +1063,16 @@ public class JSONObjectTest {
|
||||
"\"tooManyZeros\":00,"+
|
||||
"\"negativeInfinite\":-Infinity,"+
|
||||
"\"negativeNaN\":-NaN,"+
|
||||
"\"negativeNaNWithLeadingZeros\":-00NaN,"+
|
||||
"\"negativeFraction\":-.01,"+
|
||||
"\"tooManyZerosFraction\":00.001,"+
|
||||
"\"negativeHexFloat\":-0x1.fffp1,"+
|
||||
"\"hexFloat\":0x1.0P-1074,"+
|
||||
"\"floatIdentifier\":0.1f,"+
|
||||
"\"doubleIdentifier\":0.1d"+
|
||||
"\"doubleIdentifier\":0.1d,"+
|
||||
"\"integerWithLeadingZeros\":000900,"+
|
||||
"\"integerWithAllZeros\":00000,"+
|
||||
"\"compositeWithLeadingZeros\":00800.90d"+
|
||||
"}";
|
||||
JSONObject jsonObject = new JSONObject(str);
|
||||
Object obj;
|
||||
@ -1085,10 +1089,17 @@ public class JSONObjectTest {
|
||||
obj = jsonObject.get("negativeNaN");
|
||||
assertTrue( "negativeNaN currently evaluates to string",
|
||||
obj.equals("-NaN"));
|
||||
obj = jsonObject.get("negativeNaNWithLeadingZeros");
|
||||
assertTrue( "negativeNaNWithLeadingZeros currently evaluates to string",
|
||||
obj.equals("-00NaN"));
|
||||
assertTrue( "negativeFraction currently evaluates to double -0.01",
|
||||
jsonObject.get( "negativeFraction" ).equals(BigDecimal.valueOf(-0.01)));
|
||||
assertTrue( "tooManyZerosFraction currently evaluates to double 0.001",
|
||||
jsonObject.get( "tooManyZerosFraction" ).equals(BigDecimal.valueOf(0.001)));
|
||||
assertTrue( "tooManyZerosFraction currently evaluates to double 0.001",
|
||||
jsonObject.getLong( "tooManyZerosFraction" )==0);
|
||||
assertTrue( "tooManyZerosFraction currently evaluates to double 0.001",
|
||||
jsonObject.optLong( "tooManyZerosFraction" )==0);
|
||||
assertTrue( "negativeHexFloat currently evaluates to double -3.99951171875",
|
||||
jsonObject.get( "negativeHexFloat" ).equals(Double.valueOf(-3.99951171875)));
|
||||
assertTrue("hexFloat currently evaluates to double 4.9E-324",
|
||||
@ -1097,6 +1108,28 @@ public class JSONObjectTest {
|
||||
jsonObject.get("floatIdentifier").equals(Double.valueOf(0.1)));
|
||||
assertTrue("doubleIdentifier currently evaluates to double 0.1",
|
||||
jsonObject.get("doubleIdentifier").equals(Double.valueOf(0.1)));
|
||||
assertTrue("Integer does not evaluate to 900",
|
||||
jsonObject.get("integerWithLeadingZeros").equals(900));
|
||||
assertTrue("Integer does not evaluate to 900",
|
||||
jsonObject.getInt("integerWithLeadingZeros")==900);
|
||||
assertTrue("Integer does not evaluate to 900",
|
||||
jsonObject.optInt("integerWithLeadingZeros")==900);
|
||||
assertTrue("Integer does not evaluate to 0",
|
||||
jsonObject.get("integerWithAllZeros").equals("00000"));
|
||||
assertTrue("Integer does not evaluate to 0",
|
||||
jsonObject.getInt("integerWithAllZeros")==0);
|
||||
assertTrue("Integer does not evaluate to 0",
|
||||
jsonObject.optInt("integerWithAllZeros")==0);
|
||||
assertTrue("Double does not evaluate to 800.90",
|
||||
jsonObject.get("compositeWithLeadingZeros").equals(800.90));
|
||||
assertTrue("Double does not evaluate to 800.90",
|
||||
jsonObject.getDouble("compositeWithLeadingZeros")==800.9d);
|
||||
assertTrue("Integer does not evaluate to 800",
|
||||
jsonObject.optInt("compositeWithLeadingZeros")==800);
|
||||
assertTrue("Long does not evaluate to 800.90",
|
||||
jsonObject.getLong("compositeWithLeadingZeros")==800);
|
||||
assertTrue("Long does not evaluate to 800.90",
|
||||
jsonObject.optLong("compositeWithLeadingZeros")==800);
|
||||
Util.checkJSONObjectMaps(jsonObject);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user