-
Notifications
You must be signed in to change notification settings - Fork 4.4k
Adds support to BigDecimal in JsonPrimitive#equals
#2364
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
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 yandy 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.
eamonnmcmanus
left a comment
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
BigDeciamalis 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
BigDecimaland in that case use the properequalsmethod.Checklist
null@since $next-version$(
$next-version$is a special placeholder which is automatically replaced during release)TestCase)mvn clean verify javadoc:jarpasses without errors