diff --git a/gson/src/main/java/com/google/gson/JsonPrimitive.java b/gson/src/main/java/com/google/gson/JsonPrimitive.java index 5e95d5a82b..4bb9e9b6e8 100644 --- a/gson/src/main/java/com/google/gson/JsonPrimitive.java +++ b/gson/src/main/java/com/google/gson/JsonPrimitive.java @@ -267,6 +267,12 @@ public boolean equals(Object obj) { if (value == null) { return other.value == null; } + if (isBigNumber(this) || isBigNumber(other)) { + // As a BigDecimal is essentially a wrapper around a BigInteger that + // "remembers where the decimal point is", casting BigInteger to BigDecimal + // makes more sense, avoiding max long/double values comparison. + return getAsBigDecimal().equals(other.getAsBigDecimal()); + } if (isIntegral(this) && isIntegral(other)) { return getAsNumber().longValue() == other.getAsNumber().longValue(); } @@ -292,4 +298,16 @@ private static boolean isIntegral(JsonPrimitive primitive) { } return false; } + + private static boolean isBigInteger(JsonPrimitive primitive) { + return primitive.value instanceof BigDecimal; + } + + private static boolean isBigDecimal(JsonPrimitive primitive) { + return primitive.value instanceof BigDecimal; + } + + private static boolean isBigNumber(JsonPrimitive primitive) { + return isBigDecimal(primitive) || isBigInteger(primitive); + } }