@@ -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