Skip to content

Commit

Permalink
Adds support to BigDecimal in JsonPrimitive#equals (google#2364)
Browse files Browse the repository at this point in the history
* Adds support to `BigDecimal`

Adds to the JsonPrimitive#equals the possibility to support BigDecimal

* Adds test

Adds test to check if the equals work with BigDecimals. Code snippet from issue google#904

* Implements review comments

Replaces the `.equals` method with the `compareTo` in the `JsonPrimitive#equals`

Change the ternary operator from `||` to `&&` so we are sure that both are `BigDecimal`

Implements tests

* Changes to follow the google-style-guide

* implements review comment

Co-authored-by: Marcono1234 <[email protected]>

* Fixes the `OperatorPrecedence` warn

* Implements code improvements

- Extracts `thisAsDouble` & `otherAsDouble` variables to avoid double functions calls.

- Adds a comment to improve the code readability.

* Implements `BigDecimal` check in the `JsonPrimitive.equals()`

* Formats the code with `spotless:apply`

---------

Co-authored-by: Marcono1234 <[email protected]>
  • Loading branch information
MaicolAntali and Marcono1234 authored Feb 9, 2024
1 parent 29ea319 commit db61bb0
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 5 deletions.
15 changes: 10 additions & 5 deletions gson/src/main/java/com/google/gson/JsonPrimitive.java
Original file line number Diff line number Diff line change
Expand Up @@ -293,11 +293,16 @@ public boolean equals(Object obj) {
: this.getAsNumber().longValue() == other.getAsNumber().longValue();
}
if (value instanceof Number && other.value instanceof Number) {
double a = getAsNumber().doubleValue();
// Java standard types other than double return true for two NaN. So, need
// special handling for double.
double b = other.getAsNumber().doubleValue();
return a == b || (Double.isNaN(a) && Double.isNaN(b));
if (value instanceof BigDecimal && other.value instanceof BigDecimal) {
// Uses compareTo to ignore scale of values, e.g. `0` and `0.00` should be considered equal
return this.getAsBigDecimal().compareTo(other.getAsBigDecimal()) == 0;
}

double thisAsDouble = this.getAsDouble();
double otherAsDouble = other.getAsDouble();
// Don't use Double.compare(double, double) because that considers -0.0 and +0.0 not equal
return (thisAsDouble == otherAsDouble)
|| (Double.isNaN(thisAsDouble) && Double.isNaN(otherAsDouble));
}
return value.equals(other.value);
}
Expand Down
31 changes: 31 additions & 0 deletions gson/src/test/java/com/google/gson/JsonPrimitiveTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -321,4 +321,35 @@ public void testDeepCopy() {
JsonPrimitive a = new JsonPrimitive("a");
assertThat(a).isSameInstanceAs(a.deepCopy()); // Primitives are immutable!
}

@Test
public void testBigDecimalEquals() {
JsonPrimitive small = new JsonPrimitive(1.0);
JsonPrimitive large = new JsonPrimitive(2.0);
assertThat(small.equals(large)).isFalse();

BigDecimal doubleMax = BigDecimal.valueOf(Double.MAX_VALUE);
JsonPrimitive smallBD = new JsonPrimitive(doubleMax.add(new BigDecimal("100.0")));
JsonPrimitive largeBD = new JsonPrimitive(doubleMax.add(new BigDecimal("200.0")));
assertThat(smallBD.equals(largeBD)).isFalse();
}

@Test
public void testBigDecimalEqualsZero() {
assertThat(
new JsonPrimitive(new BigDecimal("0.0"))
.equals(new JsonPrimitive(new BigDecimal("0.00"))))
.isTrue();

assertThat(
new JsonPrimitive(new BigDecimal("0.00"))
.equals(new JsonPrimitive(Double.valueOf("0.00"))))
.isTrue();
}

@Test
public void testEqualsDoubleNaNAndBigDecimal() {
assertThat(new JsonPrimitive(Double.NaN).equals(new JsonPrimitive(new BigDecimal("1.0"))))
.isFalse();
}
}

0 comments on commit db61bb0

Please sign in to comment.