-
Notifications
You must be signed in to change notification settings - Fork 4.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Adds support to BigDecimal
in JsonPrimitive#equals
#2364
Conversation
Adds to the JsonPrimitive#equals the possibility to support BigDecimal
Adds test to check if the equals work with BigDecimals. Code snippet from issue google#904
public void testBigDecimalEquals() { | ||
JsonPrimitive small = new JsonPrimitive(1.0); | ||
JsonPrimitive large = new JsonPrimitive(2.0); | ||
assertThat(small.equals(large)).isFalse(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This assert probably is overkill because is already tested here:
gson/gson/src/test/java/com/google/gson/JsonPrimitiveTest.java
Lines 246 to 250 in 3adead6
public void testFloatEqualsBigDecimal() { | |
JsonPrimitive p1 = new JsonPrimitive(10.25F); | |
JsonPrimitive p2 = new JsonPrimitive(new BigDecimal("10.25")); | |
assertThat(p1).isEqualTo(p2); | |
assertThat(p1.hashCode()).isEqualTo(p2.hashCode()); |
It's here to be consistent with the code in the issue #904
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
Co-authored-by: Marcono1234 <Marcono1234@users.noreply.github.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@MaicolAntali, could you please merge main
into your branch and fix the new Error Prone warning:
[WARNING] /gson/src/main/java/com/google/gson/JsonPrimitive.java:[294,47] [OperatorPrecedence] Use grouping parenthesis to make the operator precedence explicit
(see https://errorprone.info/bugpattern/OperatorPrecedence)
Did you mean 'return (this.value instanceof BigDecimal && other.value instanceof BigDecimal)'?
To me these changes look reasonable, and they should solve #904. I assume there might be some other cases where comparing BigDecimal
with primitive values such as double
or long
might still cause precision loss, but if necessary that can be addressed later.
@eamonnmcmanus, what do you think?
- Extracts `thisAsDouble` & `otherAsDouble` variables to avoid double functions calls. - Adds a comment to improve the code readability.
@MaicolAntali, could you please merge |
Don't worry, help it's a pleasure! |
// Uses compareTo to ignore scale of values, e.g. `0` and `0.00` should be considered equal | ||
return this.getAsBigDecimal().compareTo(other.getAsBigDecimal()) == 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As side note / for future reference: I originally proposed using compareTo
when this code was also comparing BigDecimal
with non-BigDecimal
, see #2364 (comment).
However, using compareTo
instead of equals
here has another advantage: It ensures JsonPrimitive.equals
is transitive (as required by Object.equals
), at least when wrapping a BigDecimal
.
(
x equals y
andy equals z
) impliesx equals z
Now let
x = new JsonPrimitive(new BigDecimal("0"))
y = new JsonPrimitive(0.0d)
z = new JsonPrimitive(new BigDecimal("0.00"))
Using compareTo
makes sure that equals
is transitive. Whereas using BigDecimal.equals
here would cause: x equals y
and y equals z
(because they fall back to double
comparison), but x !equals z
, which would not be transitive.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for doing this! I ran it against all of Google's internal tests and everything passed.
* 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 <Marcono1234@users.noreply.github.com> * 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 <Marcono1234@users.noreply.github.com>
Purpose
Fixes #904
Description
Currently a
BigDeciamal
is cast to a double and this can give issue if the number doesn't fit in it.I have implemented a ternary operator to check if a number is a
BigDecimal
and in that case use the properequals
method.Checklist
null
@since $next-version$
(
$next-version$
is a special placeholder which is automatically replaced during release)TestCase
)mvn clean verify javadoc:jar
passes without errors