mirror of
https://github.com/stleary/JSON-java.git
synced 2025-08-03 03:15:32 -04:00
fixes issue #573 by added specific compare of numeric types
This commit is contained in:
parent
e4b76d6588
commit
11e6b1af7e
@ -1374,6 +1374,8 @@ public class JSONArray implements Iterable<Object> {
|
|||||||
if (!((JSONArray)valueThis).similar(valueOther)) {
|
if (!((JSONArray)valueThis).similar(valueOther)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
} else if (valueThis instanceof Number && valueOther instanceof Number) {
|
||||||
|
return JSONObject.isNumberSimilar((Number)valueThis, (Number)valueOther);
|
||||||
} else if (!valueThis.equals(valueOther)) {
|
} else if (!valueThis.equals(valueOther)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -2073,6 +2073,8 @@ public class JSONObject {
|
|||||||
if (!((JSONArray)valueThis).similar(valueOther)) {
|
if (!((JSONArray)valueThis).similar(valueOther)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
} else if (valueThis instanceof Number && valueOther instanceof Number) {
|
||||||
|
return isNumberSimilar((Number)valueThis, (Number)valueOther);
|
||||||
} else if (!valueThis.equals(valueOther)) {
|
} else if (!valueThis.equals(valueOther)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -2083,6 +2085,55 @@ public class JSONObject {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compares two numbers to see if they are similar.
|
||||||
|
*
|
||||||
|
* If either of the numbers are Double or Float instances, then they are checked to have
|
||||||
|
* a finite value. If either value is not finite (NaN or ±infinity), then this
|
||||||
|
* function will always return false. If both numbers are finite, they are first checked
|
||||||
|
* to be the same type and implement {@link Comparable}. If they do, then the actual
|
||||||
|
* {@link Comparable#compareTo(Object)} is called. If they are not the same type, or don't
|
||||||
|
* implement Comparable, then they are converted to {@link BigDecimal}s. Finally the
|
||||||
|
* BigDecimal values are compared using {@link BigDecimal#compareTo(BigDecimal)}.
|
||||||
|
*
|
||||||
|
* @param l the Left value to compare. Can not be <code>null</code>.
|
||||||
|
* @param r the right value to compare. Can not be <code>null</code>.
|
||||||
|
* @return true if the numbers are similar, false otherwise.
|
||||||
|
*/
|
||||||
|
static boolean isNumberSimilar(Number l, Number r) {
|
||||||
|
if (!numberIsFinite(l) || !numberIsFinite(r)) {
|
||||||
|
// non-finite numbers are never similar
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if the classes are the same and implement Comparable
|
||||||
|
// then use the built in compare first.
|
||||||
|
if(l.getClass().equals(r.getClass()) && l instanceof Comparable) {
|
||||||
|
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||||
|
int compareTo = ((Comparable)l).compareTo(r);
|
||||||
|
return compareTo==0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// BigDecimal should be able to handle all of our number types that we support through
|
||||||
|
// documentation. Convert to BigDecimal first, then use the Compare method to
|
||||||
|
// decide equality.
|
||||||
|
final BigDecimal lBigDecimal = objectToBigDecimal(l, null);
|
||||||
|
final BigDecimal rBigDecimal = objectToBigDecimal(r, null);
|
||||||
|
if (lBigDecimal == null || rBigDecimal == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return lBigDecimal.compareTo(rBigDecimal) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean numberIsFinite(Number n) {
|
||||||
|
if (n instanceof Double && (((Double) n).isInfinite() || ((Double) n).isNaN())) {
|
||||||
|
return false;
|
||||||
|
} else if (n instanceof Float && (((Float) n).isInfinite() || ((Float) n).isNaN())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests if the value should be tried as a decimal. It makes no test if there are actual digits.
|
* Tests if the value should be tried as a decimal. It makes no test if there are actual digits.
|
||||||
*
|
*
|
||||||
@ -2354,7 +2405,7 @@ public class JSONObject {
|
|||||||
*/
|
*/
|
||||||
public static Object wrap(Object object) {
|
public static Object wrap(Object object) {
|
||||||
try {
|
try {
|
||||||
if (object == null) {
|
if (NULL.equals(object)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (object instanceof JSONObject || object instanceof JSONArray
|
if (object instanceof JSONObject || object instanceof JSONArray
|
||||||
|
Loading…
x
Reference in New Issue
Block a user