@@ -838,7 +838,7 @@ public static String numberToString(Number number) throws JSONException {
838838 }
839839 testValidity (number );
840840
841- // Shave off trailing zeros and decimal point, if possible.
841+ // Shave off trailing zeros and decimal point, if possible.
842842
843843 String string = number .toString ();
844844 if (string .indexOf ('.' ) > 0 && string .indexOf ('e' ) < 0
@@ -1693,7 +1693,18 @@ public static String valueToString(Object value) throws JSONException {
16931693 throw new JSONException ("Bad value from toJSONString: " + object );
16941694 }
16951695 if (value instanceof Number ) {
1696- return numberToString ((Number ) value );
1696+ // not all Numbers may match actual JSON Numbers. i.e. Fractions or Complex
1697+ final String numberAsString = numberToString ((Number ) value );
1698+ try {
1699+ // Use the BigDecimal constructor for it's parser to validate the format.
1700+ new BigDecimal (numberAsString );
1701+ // Close enough to a JSON number that we will return it unquoted
1702+ return numberAsString ;
1703+ } catch (NumberFormatException ex ){
1704+ // The Number value is not a valid JSON number.
1705+ // Instead we will quote it as a string
1706+ return quote (numberAsString );
1707+ }
16971708 }
16981709 if (value instanceof Boolean || value instanceof JSONObject
16991710 || value instanceof JSONArray ) {
@@ -1786,6 +1797,32 @@ static final Writer writeValue(Writer writer, Object value,
17861797 int indentFactor , int indent ) throws JSONException , IOException {
17871798 if (value == null || value .equals (null )) {
17881799 writer .write ("null" );
1800+ } else if (value instanceof JSONString ) {
1801+ Object o ;
1802+ try {
1803+ o = ((JSONString ) value ).toJSONString ();
1804+ } catch (Exception e ) {
1805+ throw new JSONException (e );
1806+ }
1807+ writer .write (o != null ? o .toString () : quote (value .toString ()));
1808+ } else if (value instanceof Number ) {
1809+ // not all Numbers may match actual JSON Numbers. i.e. fractions or Imaginary
1810+ final String numberAsString = numberToString ((Number ) value );
1811+ try {
1812+ // Use the BigDecimal constructor for it's parser to validate the format.
1813+ @ SuppressWarnings ("unused" )
1814+ BigDecimal testNum = new BigDecimal (numberAsString );
1815+ // Close enough to a JSON number that we will use it unquoted
1816+ writer .write (numberAsString );
1817+ } catch (NumberFormatException ex ){
1818+ // The Number value is not a valid JSON number.
1819+ // Instead we will quote it as a string
1820+ quote (numberAsString , writer );
1821+ }
1822+ } else if (value instanceof Boolean ) {
1823+ writer .write (value .toString ());
1824+ } else if (value instanceof Enum <?>) {
1825+ writer .write (quote (((Enum <?>)value ).name ()));
17891826 } else if (value instanceof JSONObject ) {
17901827 ((JSONObject ) value ).write (writer , indentFactor , indent );
17911828 } else if (value instanceof JSONArray ) {
@@ -1798,20 +1835,6 @@ static final Writer writeValue(Writer writer, Object value,
17981835 new JSONArray (coll ).write (writer , indentFactor , indent );
17991836 } else if (value .getClass ().isArray ()) {
18001837 new JSONArray (value ).write (writer , indentFactor , indent );
1801- } else if (value instanceof Number ) {
1802- writer .write (numberToString ((Number ) value ));
1803- } else if (value instanceof Boolean ) {
1804- writer .write (value .toString ());
1805- } else if (value instanceof Enum <?>) {
1806- writer .write (quote (((Enum <?>)value ).name ()));
1807- } else if (value instanceof JSONString ) {
1808- Object o ;
1809- try {
1810- o = ((JSONString ) value ).toJSONString ();
1811- } catch (Exception e ) {
1812- throw new JSONException (e );
1813- }
1814- writer .write (o != null ? o .toString () : quote (value .toString ()));
18151838 } else {
18161839 quote (value .toString (), writer );
18171840 }
0 commit comments