mirror of
https://github.com/stleary/JSON-java.git
synced 2025-08-03 11:25:30 -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.
|
* 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.
|
* 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.
|
* @return Number representation of the value.
|
||||||
* @throws NumberFormatException thrown if the value is not a valid number. A public
|
* @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.
|
* 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);
|
char initial = val.charAt(0);
|
||||||
if ((initial >= '0' && initial <= '9') || initial == '-') {
|
if ((initial >= '0' && initial <= '9') || initial == '-') {
|
||||||
// decimal representation
|
// 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.
|
// block items like 00 01 etc. Java number parsers treat these as Octal.
|
||||||
if(initial == '0' && val.length() > 1) {
|
if(initial == '0' && val.length() > 1) {
|
||||||
char at1 = val.charAt(1);
|
char at1 = val.charAt(1);
|
||||||
@ -2886,4 +2889,33 @@ public class JSONObject {
|
|||||||
"JavaBean object contains recursively defined member variable of key " + quote(key)
|
"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}")
|
@Parameters(name = "{index}: {0}")
|
||||||
public static Collection<Object[]> data() {
|
public static Collection<Object[]> data() {
|
||||||
return Arrays.asList(new Object[][]{
|
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:50.0}", 1},
|
||||||
{"{value:5e1}", 1},
|
{"{value:5e1}", 1},
|
||||||
{"{value:5E1}", 1},
|
{"{value:5E1}", 1},
|
||||||
@ -32,6 +35,7 @@ public class JSONObjectNumberTest {
|
|||||||
{"{value:-50}", -1},
|
{"{value:-50}", -1},
|
||||||
{"{value:-50.0}", -1},
|
{"{value:-50.0}", -1},
|
||||||
{"{value:-5e1}", -1},
|
{"{value:-5e1}", -1},
|
||||||
|
{"{value:-0005e1}", -1},
|
||||||
{"{value:-5E1}", -1},
|
{"{value:-5E1}", -1},
|
||||||
{"{value:-5e1}", -1},
|
{"{value:-5e1}", -1},
|
||||||
{"{value:'-50'}", -1}
|
{"{value:'-50'}", -1}
|
||||||
|
@ -1063,12 +1063,16 @@ public class JSONObjectTest {
|
|||||||
"\"tooManyZeros\":00,"+
|
"\"tooManyZeros\":00,"+
|
||||||
"\"negativeInfinite\":-Infinity,"+
|
"\"negativeInfinite\":-Infinity,"+
|
||||||
"\"negativeNaN\":-NaN,"+
|
"\"negativeNaN\":-NaN,"+
|
||||||
|
"\"negativeNaNWithLeadingZeros\":-00NaN,"+
|
||||||
"\"negativeFraction\":-.01,"+
|
"\"negativeFraction\":-.01,"+
|
||||||
"\"tooManyZerosFraction\":00.001,"+
|
"\"tooManyZerosFraction\":00.001,"+
|
||||||
"\"negativeHexFloat\":-0x1.fffp1,"+
|
"\"negativeHexFloat\":-0x1.fffp1,"+
|
||||||
"\"hexFloat\":0x1.0P-1074,"+
|
"\"hexFloat\":0x1.0P-1074,"+
|
||||||
"\"floatIdentifier\":0.1f,"+
|
"\"floatIdentifier\":0.1f,"+
|
||||||
"\"doubleIdentifier\":0.1d"+
|
"\"doubleIdentifier\":0.1d,"+
|
||||||
|
"\"integerWithLeadingZeros\":000900,"+
|
||||||
|
"\"integerWithAllZeros\":00000,"+
|
||||||
|
"\"compositeWithLeadingZeros\":00800.90d"+
|
||||||
"}";
|
"}";
|
||||||
JSONObject jsonObject = new JSONObject(str);
|
JSONObject jsonObject = new JSONObject(str);
|
||||||
Object obj;
|
Object obj;
|
||||||
@ -1085,10 +1089,17 @@ public class JSONObjectTest {
|
|||||||
obj = jsonObject.get("negativeNaN");
|
obj = jsonObject.get("negativeNaN");
|
||||||
assertTrue( "negativeNaN currently evaluates to string",
|
assertTrue( "negativeNaN currently evaluates to string",
|
||||||
obj.equals("-NaN"));
|
obj.equals("-NaN"));
|
||||||
|
obj = jsonObject.get("negativeNaNWithLeadingZeros");
|
||||||
|
assertTrue( "negativeNaNWithLeadingZeros currently evaluates to string",
|
||||||
|
obj.equals("-00NaN"));
|
||||||
assertTrue( "negativeFraction currently evaluates to double -0.01",
|
assertTrue( "negativeFraction currently evaluates to double -0.01",
|
||||||
jsonObject.get( "negativeFraction" ).equals(BigDecimal.valueOf(-0.01)));
|
jsonObject.get( "negativeFraction" ).equals(BigDecimal.valueOf(-0.01)));
|
||||||
assertTrue( "tooManyZerosFraction currently evaluates to double 0.001",
|
assertTrue( "tooManyZerosFraction currently evaluates to double 0.001",
|
||||||
jsonObject.get( "tooManyZerosFraction" ).equals(BigDecimal.valueOf(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",
|
assertTrue( "negativeHexFloat currently evaluates to double -3.99951171875",
|
||||||
jsonObject.get( "negativeHexFloat" ).equals(Double.valueOf(-3.99951171875)));
|
jsonObject.get( "negativeHexFloat" ).equals(Double.valueOf(-3.99951171875)));
|
||||||
assertTrue("hexFloat currently evaluates to double 4.9E-324",
|
assertTrue("hexFloat currently evaluates to double 4.9E-324",
|
||||||
@ -1097,6 +1108,28 @@ public class JSONObjectTest {
|
|||||||
jsonObject.get("floatIdentifier").equals(Double.valueOf(0.1)));
|
jsonObject.get("floatIdentifier").equals(Double.valueOf(0.1)));
|
||||||
assertTrue("doubleIdentifier currently evaluates to double 0.1",
|
assertTrue("doubleIdentifier currently evaluates to double 0.1",
|
||||||
jsonObject.get("doubleIdentifier").equals(Double.valueOf(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);
|
Util.checkJSONObjectMaps(jsonObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user