Skip to content

Commit c28a2bd

Browse files
author
John J. Aylward
committed
* reverts changes to getDouble and related optDouble and optFloat
* Updates optNumber to be smarter about which object it uses to parse strings
1 parent 382f62e commit c28a2bd

1 file changed

Lines changed: 42 additions & 5 deletions

File tree

JSONObject.java

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -581,7 +581,7 @@ public double getDouble(String key) throws JSONException {
581581
Object object = this.get(key);
582582
try {
583583
return object instanceof Number ? ((Number) object).doubleValue()
584-
: new BigDecimal((String) object).doubleValue();
584+
: Double.parseDouble(object.toString());
585585
} catch (Exception e) {
586586
throw new JSONException("JSONObject[" + quote(key)
587587
+ "] is not a number.", e);
@@ -1068,7 +1068,7 @@ public double optDouble(String key, double defaultValue) {
10681068
}
10691069
if (val instanceof String) {
10701070
try {
1071-
return new BigDecimal((String) val).doubleValue();
1071+
return Double.parseDouble((String) val);
10721072
} catch (Exception e) {
10731073
return defaultValue;
10741074
}
@@ -1110,7 +1110,7 @@ public float optFloat(String key, float defaultValue) {
11101110
}
11111111
if (val instanceof String) {
11121112
try {
1113-
return new BigDecimal((String) val).floatValue();
1113+
return Float.parseFloat((String) val);
11141114
} catch (Exception e) {
11151115
return defaultValue;
11161116
}
@@ -1247,7 +1247,7 @@ public Number optNumber(String key) {
12471247
/**
12481248
* Get an optional {@link Number} value associated with a key, or the default if there
12491249
* is no such key or if the value is not a number. If the value is a string,
1250-
* an attempt will be made to evaluate it as a number ({@link BigDecimal}). This method
1250+
* an attempt will be made to evaluate it as a number. This method
12511251
* would be used in cases where type coercion of the number value is unwanted.
12521252
*
12531253
* @param key
@@ -1267,7 +1267,44 @@ public Number optNumber(String key, Number defaultValue) {
12671267

12681268
if (val instanceof String) {
12691269
try {
1270-
return new BigDecimal((String) val);
1270+
// decimal representation
1271+
if (((String)val).indexOf('.')>=0 || ((String)val).indexOf('e')>=0 || ((String)val).indexOf('E')>=0) {
1272+
// quick dirty way to see if we need a BigDecimal instead of a Double
1273+
if (((String)val).length()>14) {
1274+
return new BigDecimal((String)val);
1275+
}
1276+
return Double.valueOf((String)val);
1277+
}
1278+
// integer representation.
1279+
// This will narrow any values to the smallest reasonable Object representation
1280+
// (Integer, Long, or BigInteger)
1281+
// The compare string length method reduces GC,
1282+
// but leads to smaller integers being placed in larger wrappers even though not
1283+
// needed. i.e. 1,000,000,000 -> Long even though it's an Integer
1284+
// 1,000,000,000,000,000,000 -> BigInteger even though it's a Long
1285+
1286+
// string version
1287+
if(((String)val).length()<=9){
1288+
return Integer.valueOf((String)val);
1289+
}
1290+
if(((String)val).length()<=18){
1291+
return Long.valueOf((String)val);
1292+
}
1293+
return new BigInteger((String)val);
1294+
1295+
// BigInteger version: We use a similar bitLenth compare as
1296+
// BigInteger#intValueExact uses. Increases GC, but objects hold
1297+
// only what they need. i.e. Less runtime overhead if the value is
1298+
// long lived. Which is the better tradeoff?
1299+
1300+
//BigInteger bi = new BigInteger((String)val);
1301+
//if(bi.bitLength()<=31){
1302+
// return Integer.valueOf(bi.intValue());
1303+
//}
1304+
//if(bi.bitLength()<=63){
1305+
// return Long.valueOf(bi.longValue());
1306+
//}
1307+
//return bi;
12711308
} catch (Exception e) {
12721309
return defaultValue;
12731310
}

0 commit comments

Comments
 (0)