This is an automated email from the ASF dual-hosted git repository.

mattjuntunen pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-geometry.git


The following commit(s) were added to refs/heads/master by this push:
     new fc9272b  GEOMETRY-99: using Double.compare in equals and 
Double.hashCode in hashCode
fc9272b is described below

commit fc9272b2366d6b5944e1c1a9ecf568ff89f95a30
Author: Matt Juntunen <mattjuntu...@apache.org>
AuthorDate: Sat Jul 4 16:29:59 2020 -0400

    GEOMETRY-99: using Double.compare in equals and Double.hashCode in hashCode
---
 .../precision/EpsilonDoublePrecisionContext.java   |  2 +-
 .../EpsilonDoublePrecisionContextTest.java         | 19 ++++++++++++++
 .../commons/geometry/euclidean/oned/Vector1D.java  |  4 +--
 .../euclidean/threed/AffineTransformMatrix3D.java  | 25 +++++++++----------
 .../euclidean/threed/SphericalCoordinates.java     |  5 ++--
 .../geometry/euclidean/threed/Vector3D.java        |  9 ++++---
 .../threed/rotation/AxisAngleSequence.java         |  8 +++---
 .../euclidean/twod/AffineTransformMatrix2D.java    | 13 +++++-----
 .../geometry/euclidean/twod/PolarCoordinates.java  |  4 +--
 .../commons/geometry/euclidean/twod/Vector2D.java  |  6 ++---
 .../oned/AffineTransformMatrix1DTest.java          | 18 ++++++++++++++
 .../geometry/euclidean/oned/Vector1DTest.java      | 19 ++++++++++++++
 .../threed/AffineTransformMatrix3DTest.java        | 29 ++++++++++++++++++++++
 .../euclidean/threed/SphericalCoordinatesTest.java | 19 ++++++++++++++
 .../geometry/euclidean/threed/Vector3DTest.java    | 18 ++++++++++++++
 .../threed/rotation/AxisAngleSequenceTest.java     | 23 +++++++++++++++++
 .../twod/AffineTransformMatrix2DTest.java          | 27 ++++++++++++++++++++
 .../euclidean/twod/PolarCoordinatesTest.java       | 18 ++++++++++++++
 .../geometry/euclidean/twod/Vector2DTest.java      | 18 ++++++++++++++
 .../geometry/spherical/oned/Point1STest.java       | 19 ++++++++++++++
 20 files changed, 263 insertions(+), 40 deletions(-)

diff --git 
a/commons-geometry-core/src/main/java/org/apache/commons/geometry/core/precision/EpsilonDoublePrecisionContext.java
 
b/commons-geometry-core/src/main/java/org/apache/commons/geometry/core/precision/EpsilonDoublePrecisionContext.java
index bfa6446..e9a5121 100644
--- 
a/commons-geometry-core/src/main/java/org/apache/commons/geometry/core/precision/EpsilonDoublePrecisionContext.java
+++ 
b/commons-geometry-core/src/main/java/org/apache/commons/geometry/core/precision/EpsilonDoublePrecisionContext.java
@@ -94,7 +94,7 @@ public class EpsilonDoublePrecisionContext extends 
DoublePrecisionContext implem
 
         final EpsilonDoublePrecisionContext other = 
(EpsilonDoublePrecisionContext) obj;
 
-        return this.epsilon == other.epsilon;
+        return Double.compare(this.epsilon, other.epsilon) == 0;
     }
 
     /** {@inheritDoc} **/
diff --git 
a/commons-geometry-core/src/test/java/org/apache/commons/geometry/core/precision/EpsilonDoublePrecisionContextTest.java
 
b/commons-geometry-core/src/test/java/org/apache/commons/geometry/core/precision/EpsilonDoublePrecisionContextTest.java
index e0e26f9..d8d4164 100644
--- 
a/commons-geometry-core/src/test/java/org/apache/commons/geometry/core/precision/EpsilonDoublePrecisionContextTest.java
+++ 
b/commons-geometry-core/src/test/java/org/apache/commons/geometry/core/precision/EpsilonDoublePrecisionContextTest.java
@@ -209,6 +209,25 @@ public class EpsilonDoublePrecisionContextTest {
     }
 
     @Test
+    public void testEqualsAndHashCode_signedZeroConsistency() {
+        // arrange
+        final EpsilonDoublePrecisionContext a = new 
EpsilonDoublePrecisionContext(0.0);
+        final EpsilonDoublePrecisionContext b = new 
EpsilonDoublePrecisionContext(-0.0);
+        final EpsilonDoublePrecisionContext c = new 
EpsilonDoublePrecisionContext(0.0);
+        final EpsilonDoublePrecisionContext d = new 
EpsilonDoublePrecisionContext(-0.0);
+
+        // act/assert
+        Assert.assertFalse(a.equals(b));
+        Assert.assertNotEquals(a.hashCode(), b.hashCode());
+
+        Assert.assertTrue(a.equals(c));
+        Assert.assertEquals(a.hashCode(), c.hashCode());
+
+        Assert.assertTrue(b.equals(d));
+        Assert.assertEquals(b.hashCode(), d.hashCode());
+    }
+
+    @Test
     public void testToString() {
         // arrange
         final EpsilonDoublePrecisionContext a = new 
EpsilonDoublePrecisionContext(1d);
diff --git 
a/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/oned/Vector1D.java
 
b/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/oned/Vector1D.java
index b046c8a..ed968fe 100644
--- 
a/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/oned/Vector1D.java
+++ 
b/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/oned/Vector1D.java
@@ -277,18 +277,16 @@ public class Vector1D extends EuclideanVector<Vector1D> {
      */
     @Override
     public boolean equals(final Object other) {
-
         if (this == other) {
             return true;
         }
-
         if (other instanceof Vector1D) {
             final Vector1D rhs = (Vector1D) other;
             if (rhs.isNaN()) {
                 return this.isNaN();
             }
 
-            return x == rhs.x;
+            return Double.compare(x, rhs.x) == 0;
         }
         return false;
     }
diff --git 
a/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/threed/AffineTransformMatrix3D.java
 
b/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/threed/AffineTransformMatrix3D.java
index ab46582..bbda043 100644
--- 
a/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/threed/AffineTransformMatrix3D.java
+++ 
b/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/threed/AffineTransformMatrix3D.java
@@ -24,7 +24,6 @@ import 
org.apache.commons.geometry.euclidean.internal.Matrices;
 import org.apache.commons.geometry.euclidean.internal.Vectors;
 import 
org.apache.commons.geometry.euclidean.threed.rotation.QuaternionRotation;
 import org.apache.commons.numbers.arrays.LinearCombination;
-import org.apache.commons.numbers.core.Precision;
 
 /** Class using a matrix to represent affine transformations in 3 dimensional 
Euclidean space.
  *
@@ -442,20 +441,20 @@ public final class AffineTransformMatrix3D extends 
AbstractAffineTransformMatrix
 
         final AffineTransformMatrix3D other = (AffineTransformMatrix3D) obj;
 
-        return Precision.equals(this.m00, other.m00) &&
-                Precision.equals(this.m01, other.m01) &&
-                Precision.equals(this.m02, other.m02) &&
-                Precision.equals(this.m03, other.m03) &&
+        return Double.compare(this.m00, other.m00) == 0 &&
+                Double.compare(this.m01, other.m01) == 0 &&
+                Double.compare(this.m02, other.m02) == 0 &&
+                Double.compare(this.m03, other.m03) == 0 &&
 
-                Precision.equals(this.m10, other.m10) &&
-                Precision.equals(this.m11, other.m11) &&
-                Precision.equals(this.m12, other.m12) &&
-                Precision.equals(this.m13, other.m13) &&
+                Double.compare(this.m10, other.m10) == 0 &&
+                Double.compare(this.m11, other.m11) == 0 &&
+                Double.compare(this.m12, other.m12) == 0 &&
+                Double.compare(this.m13, other.m13) == 0 &&
 
-                Precision.equals(this.m20, other.m20) &&
-                Precision.equals(this.m21, other.m21) &&
-                Precision.equals(this.m22, other.m22) &&
-                Precision.equals(this.m23, other.m23);
+                Double.compare(this.m20, other.m20) == 0 &&
+                Double.compare(this.m21, other.m21) == 0 &&
+                Double.compare(this.m22, other.m22) == 0 &&
+                Double.compare(this.m23, other.m23) == 0;
     }
 
     /** {@inheritDoc} */
diff --git 
a/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/threed/SphericalCoordinates.java
 
b/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/threed/SphericalCoordinates.java
index cdab529..b7415e7 100644
--- 
a/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/threed/SphericalCoordinates.java
+++ 
b/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/threed/SphericalCoordinates.java
@@ -181,14 +181,15 @@ public final class SphericalCoordinates implements 
Spatial {
         if (this == other) {
             return true;
         }
-
         if (other instanceof SphericalCoordinates) {
             final SphericalCoordinates rhs = (SphericalCoordinates) other;
             if (rhs.isNaN()) {
                 return this.isNaN();
             }
 
-            return (radius == rhs.radius) && (azimuth == rhs.azimuth) && 
(polar == rhs.polar);
+            return Double.compare(radius, rhs.radius) == 0 &&
+                    Double.compare(azimuth, rhs.azimuth) == 0 &&
+                    Double.compare(polar, rhs.polar) == 0;
         }
         return false;
     }
diff --git 
a/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/threed/Vector3D.java
 
b/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/threed/Vector3D.java
index de90eab..acf0d65 100644
--- 
a/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/threed/Vector3D.java
+++ 
b/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/threed/Vector3D.java
@@ -399,10 +399,10 @@ public class Vector3D extends 
MultiDimensionalEuclideanVector<Vector3D> {
         if (isNaN()) {
             return 642;
         }
-        return 643 * (164 * Double.hashCode(x) +  3 * Double.hashCode(y) +  
Double.hashCode(z));
+        return 643 * (164 * Double.hashCode(x) + 3 * Double.hashCode(y) + 
Double.hashCode(z));
     }
 
-    /**
+    /**d
      * Test for the equality of two vector instances.
      * <p>
      * If all coordinates of two vectors are exactly the same, and none are
@@ -426,14 +426,15 @@ public class Vector3D extends 
MultiDimensionalEuclideanVector<Vector3D> {
         if (this == other) {
             return true;
         }
-
         if (other instanceof Vector3D) {
             final Vector3D rhs = (Vector3D) other;
             if (rhs.isNaN()) {
                 return this.isNaN();
             }
 
-            return (x == rhs.x) && (y == rhs.y) && (z == rhs.z);
+            return Double.compare(x, rhs.x) == 0 &&
+                    Double.compare(y, rhs.y) == 0 &&
+                    Double.compare(z, rhs.z) == 0;
         }
         return false;
     }
diff --git 
a/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/threed/rotation/AxisAngleSequence.java
 
b/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/threed/rotation/AxisAngleSequence.java
index 1f42ee7..494a3f1 100644
--- 
a/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/threed/rotation/AxisAngleSequence.java
+++ 
b/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/threed/rotation/AxisAngleSequence.java
@@ -19,8 +19,6 @@ package org.apache.commons.geometry.euclidean.threed.rotation;
 import java.util.Arrays;
 import java.util.Objects;
 
-import org.apache.commons.numbers.core.Precision;
-
 /** <p>
  * Class representing a sequence of axis-angle rotations. These types of
  * rotations are commonly called <em>Euler angles</em>, <em>Tait-Bryan 
angles</em>,
@@ -158,9 +156,9 @@ public final class AxisAngleSequence {
 
         return this.referenceFrame == other.referenceFrame &&
                 this.axisSequence == other.axisSequence &&
-                Precision.equals(this.angle1, other.angle1) &&
-                Precision.equals(this.angle2, other.angle2) &&
-                Precision.equals(this.angle3, other.angle3);
+                Double.compare(this.angle1, other.angle1) == 0 &&
+                Double.compare(this.angle2, other.angle2) == 0 &&
+                Double.compare(this.angle3, other.angle3) == 0;
     }
 
     /** {@inheritDoc} */
diff --git 
a/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/twod/AffineTransformMatrix2D.java
 
b/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/twod/AffineTransformMatrix2D.java
index 17ff26b..0b7f658 100644
--- 
a/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/twod/AffineTransformMatrix2D.java
+++ 
b/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/twod/AffineTransformMatrix2D.java
@@ -24,7 +24,6 @@ import 
org.apache.commons.geometry.euclidean.internal.Matrices;
 import org.apache.commons.geometry.euclidean.internal.Vectors;
 import org.apache.commons.geometry.euclidean.twod.rotation.Rotation2D;
 import org.apache.commons.numbers.arrays.LinearCombination;
-import org.apache.commons.numbers.core.Precision;
 
 /** Class using a matrix to represent affine transformations in 2 dimensional 
Euclidean space.
 *
@@ -397,13 +396,13 @@ public final class AffineTransformMatrix2D extends 
AbstractAffineTransformMatrix
 
         final AffineTransformMatrix2D other = (AffineTransformMatrix2D) obj;
 
-        return Precision.equals(this.m00, other.m00) &&
-                Precision.equals(this.m01, other.m01) &&
-                Precision.equals(this.m02, other.m02) &&
+        return Double.compare(this.m00, other.m00) == 0 &&
+                Double.compare(this.m01, other.m01) == 0 &&
+                Double.compare(this.m02, other.m02) == 0 &&
 
-                Precision.equals(this.m10, other.m10) &&
-                Precision.equals(this.m11, other.m11) &&
-                Precision.equals(this.m12, other.m12);
+                Double.compare(this.m10, other.m10) == 0 &&
+                Double.compare(this.m11, other.m11) == 0 &&
+                Double.compare(this.m12, other.m12) == 0;
     }
 
     /** {@inheritDoc} */
diff --git 
a/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/twod/PolarCoordinates.java
 
b/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/twod/PolarCoordinates.java
index bcaf2bc..bb66412 100644
--- 
a/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/twod/PolarCoordinates.java
+++ 
b/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/twod/PolarCoordinates.java
@@ -151,14 +151,14 @@ public final class PolarCoordinates implements Spatial {
         if (this == other) {
             return true;
         }
-
         if (other instanceof PolarCoordinates) {
             final PolarCoordinates rhs = (PolarCoordinates) other;
             if (rhs.isNaN()) {
                 return this.isNaN();
             }
 
-            return (radius == rhs.radius) && (azimuth == rhs.azimuth);
+            return Double.compare(radius, rhs.radius) == 0 &&
+                    Double.compare(azimuth, rhs.azimuth) == 0;
         }
         return false;
     }
diff --git 
a/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/twod/Vector2D.java
 
b/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/twod/Vector2D.java
index 1cdd869..091ec4c 100644
--- 
a/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/twod/Vector2D.java
+++ 
b/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/twod/Vector2D.java
@@ -342,7 +342,7 @@ public class Vector2D extends 
MultiDimensionalEuclideanVector<Vector2D> {
         if (isNaN()) {
             return 542;
         }
-        return 122 * (76 * Double.hashCode(x) +  Double.hashCode(y));
+        return 122 * (76 * Double.hashCode(x) + Double.hashCode(y));
     }
 
     /**
@@ -369,14 +369,14 @@ public class Vector2D extends 
MultiDimensionalEuclideanVector<Vector2D> {
         if (this == other) {
             return true;
         }
-
         if (other instanceof Vector2D) {
             final Vector2D rhs = (Vector2D) other;
             if (rhs.isNaN()) {
                 return this.isNaN();
             }
 
-            return (x == rhs.x) && (y == rhs.y);
+            return Double.compare(x, rhs.x) == 0 &&
+                    Double.compare(y, rhs.y) == 0;
         }
         return false;
     }
diff --git 
a/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/oned/AffineTransformMatrix1DTest.java
 
b/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/oned/AffineTransformMatrix1DTest.java
index e4bd869..bdec5ad 100644
--- 
a/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/oned/AffineTransformMatrix1DTest.java
+++ 
b/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/oned/AffineTransformMatrix1DTest.java
@@ -734,6 +734,24 @@ public class AffineTransformMatrix1DTest {
     }
 
     @Test
+    public void testEqualsAndHashCode_signedZeroConsistency() {
+        // arrange
+        final AffineTransformMatrix1D a = AffineTransformMatrix1D.of(0.0, 
-0.0);
+        final AffineTransformMatrix1D b = AffineTransformMatrix1D.of(-0.0, 
0.0);
+        final AffineTransformMatrix1D c = AffineTransformMatrix1D.of(0.0, 
-0.0);
+        final AffineTransformMatrix1D d = AffineTransformMatrix1D.of(-0.0, 
0.0);
+
+        // act/assert
+        Assert.assertFalse(a.equals(b));
+
+        Assert.assertTrue(a.equals(c));
+        Assert.assertEquals(a.hashCode(), c.hashCode());
+
+        Assert.assertTrue(b.equals(d));
+        Assert.assertEquals(b.hashCode(), d.hashCode());
+    }
+
+    @Test
     public void testToString() {
         // arrange
         final AffineTransformMatrix1D a = AffineTransformMatrix1D.of(1, 2);
diff --git 
a/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/oned/Vector1DTest.java
 
b/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/oned/Vector1DTest.java
index 98cc9fb..a392736 100644
--- 
a/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/oned/Vector1DTest.java
+++ 
b/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/oned/Vector1DTest.java
@@ -599,6 +599,25 @@ public class Vector1DTest {
     }
 
     @Test
+    public void testEqualsAndHashCode_signedZeroConsistency() {
+        // arrange
+        final Vector1D a = Vector1D.of(0.0);
+        final Vector1D b = Vector1D.of(-0.0);
+        final Vector1D c = Vector1D.of(0.0);
+        final Vector1D d = Vector1D.of(-0.0);
+
+        // act/assert
+        Assert.assertFalse(a.equals(b));
+        Assert.assertNotEquals(a.hashCode(), b.hashCode());
+
+        Assert.assertTrue(a.equals(c));
+        Assert.assertEquals(a.hashCode(), c.hashCode());
+
+        Assert.assertTrue(b.equals(d));
+        Assert.assertEquals(b.hashCode(), d.hashCode());
+    }
+
+    @Test
     public void testToString() {
         // arrange
         final Vector1D v = Vector1D.of(3);
diff --git 
a/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/threed/AffineTransformMatrix3DTest.java
 
b/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/threed/AffineTransformMatrix3DTest.java
index e0e848c..aca1c30 100644
--- 
a/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/threed/AffineTransformMatrix3DTest.java
+++ 
b/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/threed/AffineTransformMatrix3DTest.java
@@ -1181,6 +1181,35 @@ public class AffineTransformMatrix3DTest {
     }
 
     @Test
+    public void testEqualsAndHashCode_signedZeroConsistency() {
+        // arrange
+        final double[] arrWithPosZero = {
+            1.0, 0.0, 0.0, 0.0,
+            0.0, 1.0, 0.0, 0.0,
+            0.0, 0.0, 1.0, 0.0,
+        };
+        final double[] arrWithNegZero = {
+            1.0, 0.0, 0.0, 0.0,
+            0.0, 1.0, 0.0, 0.0,
+            0.0, 0.0, 1.0, -0.0,
+        };
+        final AffineTransformMatrix3D a = 
AffineTransformMatrix3D.of(arrWithPosZero);
+        final AffineTransformMatrix3D b = 
AffineTransformMatrix3D.of(arrWithNegZero);
+        final AffineTransformMatrix3D c = 
AffineTransformMatrix3D.of(arrWithPosZero);
+        final AffineTransformMatrix3D d = 
AffineTransformMatrix3D.of(arrWithNegZero);
+
+        // act/assert
+        Assert.assertFalse(a.equals(b));
+        Assert.assertNotEquals(a.hashCode(), b.hashCode());
+
+        Assert.assertTrue(a.equals(c));
+        Assert.assertEquals(a.hashCode(), c.hashCode());
+
+        Assert.assertTrue(b.equals(d));
+        Assert.assertEquals(b.hashCode(), d.hashCode());
+    }
+
+    @Test
     public void testToString() {
         // arrange
         final AffineTransformMatrix3D a = AffineTransformMatrix3D.of(
diff --git 
a/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/threed/SphericalCoordinatesTest.java
 
b/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/threed/SphericalCoordinatesTest.java
index ca3e220..2f740df 100644
--- 
a/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/threed/SphericalCoordinatesTest.java
+++ 
b/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/threed/SphericalCoordinatesTest.java
@@ -321,6 +321,25 @@ public class SphericalCoordinatesTest {
     }
 
     @Test
+    public void testEqualsAndHashCode_signedZeroConsistency() {
+        // arrange
+        final SphericalCoordinates a = SphericalCoordinates.of(0.0, -0.0, 0.0);
+        final SphericalCoordinates b = SphericalCoordinates.of(-0.0, 0.0, 
-0.0);
+        final SphericalCoordinates c = SphericalCoordinates.of(0.0, -0.0, 0.0);
+        final SphericalCoordinates d = SphericalCoordinates.of(-0.0, 0.0, 
-0.0);
+
+        // act/assert
+        Assert.assertFalse(a.equals(b));
+        Assert.assertNotEquals(a.hashCode(), b.hashCode());
+
+        Assert.assertTrue(a.equals(c));
+        Assert.assertEquals(a.hashCode(), c.hashCode());
+
+        Assert.assertTrue(b.equals(d));
+        Assert.assertEquals(b.hashCode(), d.hashCode());
+    }
+
+    @Test
     public void testToString() {
         // arrange
         final SphericalCoordinates sph = SphericalCoordinates.of(1, 2, 3);
diff --git 
a/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/threed/Vector3DTest.java
 
b/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/threed/Vector3DTest.java
index b89fa71..06b1d3f 100644
--- 
a/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/threed/Vector3DTest.java
+++ 
b/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/threed/Vector3DTest.java
@@ -1103,6 +1103,24 @@ public class Vector3DTest {
     }
 
     @Test
+    public void testEqualsAndHashCode_signedZeroConsistency() {
+        // arrange
+        final Vector3D a = Vector3D.of(0.0, -0.0, 0.0);
+        final Vector3D b = Vector3D.of(-0.0, 0.0, -0.0);
+        final Vector3D c = Vector3D.of(0.0, -0.0, 0.0);
+        final Vector3D d = Vector3D.of(-0.0, 0.0, -0.0);
+
+        // act/assert
+        Assert.assertFalse(a.equals(b));
+
+        Assert.assertTrue(a.equals(c));
+        Assert.assertEquals(a.hashCode(), c.hashCode());
+
+        Assert.assertTrue(b.equals(d));
+        Assert.assertEquals(b.hashCode(), d.hashCode());
+    }
+
+    @Test
     public void testToString() {
         // arrange
         final Vector3D v = Vector3D.of(1, 2, 3);
diff --git 
a/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/threed/rotation/AxisAngleSequenceTest.java
 
b/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/threed/rotation/AxisAngleSequenceTest.java
index 5494fcf..05800ff 100644
--- 
a/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/threed/rotation/AxisAngleSequenceTest.java
+++ 
b/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/threed/rotation/AxisAngleSequenceTest.java
@@ -81,6 +81,29 @@ public class AxisAngleSequenceTest {
     }
 
     @Test
+    public void testEqualsAndHashCode_signedZeroConsistency() {
+        // arrange
+        final AxisAngleSequence a = new 
AxisAngleSequence(AxisReferenceFrame.ABSOLUTE, AxisSequence.XYZ,
+                0.0, -0.0, 0.0);
+        final AxisAngleSequence b = new 
AxisAngleSequence(AxisReferenceFrame.ABSOLUTE, AxisSequence.XYZ,
+                -0.0, 0.0, -0.0);
+        final AxisAngleSequence c = new 
AxisAngleSequence(AxisReferenceFrame.ABSOLUTE, AxisSequence.XYZ,
+                0.0, -0.0, 0.0);
+        final AxisAngleSequence d = new 
AxisAngleSequence(AxisReferenceFrame.ABSOLUTE, AxisSequence.XYZ,
+                -0.0, 0.0, -0.0);
+
+        // act/assert
+        Assert.assertFalse(a.equals(b));
+        Assert.assertNotEquals(a.hashCode(), b.hashCode());
+
+        Assert.assertTrue(a.equals(c));
+        Assert.assertEquals(a.hashCode(), c.hashCode());
+
+        Assert.assertTrue(b.equals(d));
+        Assert.assertEquals(b.hashCode(), d.hashCode());
+    }
+
+    @Test
     public void testToString() {
         // arrange
         final AxisAngleSequence seq = new 
AxisAngleSequence(AxisReferenceFrame.ABSOLUTE, AxisSequence.XYZ, 1, 2, 3);
diff --git 
a/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/twod/AffineTransformMatrix2DTest.java
 
b/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/twod/AffineTransformMatrix2DTest.java
index 3e8d39d..6eedde8 100644
--- 
a/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/twod/AffineTransformMatrix2DTest.java
+++ 
b/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/twod/AffineTransformMatrix2DTest.java
@@ -1188,6 +1188,33 @@ public class AffineTransformMatrix2DTest {
     }
 
     @Test
+    public void testEqualsAndHashCode_signedZeroConsistency() {
+        // arrange
+        final double[] arrWithPosZero = {
+            1.0, 0.0, 0.0,
+            0.0, 1.0, 0.0
+        };
+        final double[] arrWithNegZero = {
+            1.0, 0.0, 0.0,
+            0.0, 1.0, -0.0
+        };
+        final AffineTransformMatrix2D a = 
AffineTransformMatrix2D.of(arrWithPosZero);
+        final AffineTransformMatrix2D b = 
AffineTransformMatrix2D.of(arrWithNegZero);
+        final AffineTransformMatrix2D c = 
AffineTransformMatrix2D.of(arrWithPosZero);
+        final AffineTransformMatrix2D d = 
AffineTransformMatrix2D.of(arrWithNegZero);
+
+        // act/assert
+        Assert.assertFalse(a.equals(b));
+        Assert.assertNotEquals(a.hashCode(), b.hashCode());
+
+        Assert.assertTrue(a.equals(c));
+        Assert.assertEquals(a.hashCode(), c.hashCode());
+
+        Assert.assertTrue(b.equals(d));
+        Assert.assertEquals(b.hashCode(), d.hashCode());
+    }
+
+    @Test
     public void testToString() {
         // arrange
         final AffineTransformMatrix2D a = AffineTransformMatrix2D.of(
diff --git 
a/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/twod/PolarCoordinatesTest.java
 
b/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/twod/PolarCoordinatesTest.java
index c6599a9..eb609d5 100644
--- 
a/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/twod/PolarCoordinatesTest.java
+++ 
b/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/twod/PolarCoordinatesTest.java
@@ -254,6 +254,24 @@ public class PolarCoordinatesTest {
     }
 
     @Test
+    public void testEqualsAndHashCode_signedZeroConsistency() {
+        // arrange
+        final PolarCoordinates a = PolarCoordinates.of(0.0, -0.0);
+        final PolarCoordinates b = PolarCoordinates.of(-0.0, 0.0);
+        final PolarCoordinates c = PolarCoordinates.of(0.0, -0.0);
+        final PolarCoordinates d = PolarCoordinates.of(-0.0, 0.0);
+
+        // act/assert
+        Assert.assertFalse(a.equals(b));
+
+        Assert.assertTrue(a.equals(c));
+        Assert.assertEquals(a.hashCode(), c.hashCode());
+
+        Assert.assertTrue(b.equals(d));
+        Assert.assertEquals(b.hashCode(), d.hashCode());
+    }
+
+    @Test
     public void testToCartesian() {
         // arrange
         final double sqrt2 = Math.sqrt(2);
diff --git 
a/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/twod/Vector2DTest.java
 
b/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/twod/Vector2DTest.java
index 5912503..ba623be 100644
--- 
a/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/twod/Vector2DTest.java
+++ 
b/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/twod/Vector2DTest.java
@@ -919,6 +919,24 @@ public class Vector2DTest {
     }
 
     @Test
+    public void testEqualsAndHashCode_signedZeroConsistency() {
+        // arrange
+        final Vector2D a = Vector2D.of(0.0, 0.0);
+        final Vector2D b = Vector2D.of(-0.0, -0.0);
+        final Vector2D c = Vector2D.of(0.0, 0.0);
+        final Vector2D d = Vector2D.of(-0.0, -0.0);
+
+        // act/assert
+        Assert.assertFalse(a.equals(b));
+
+        Assert.assertTrue(a.equals(c));
+        Assert.assertEquals(a.hashCode(), c.hashCode());
+
+        Assert.assertTrue(b.equals(d));
+        Assert.assertEquals(b.hashCode(), d.hashCode());
+    }
+
+    @Test
     public void testToString() {
         // arrange
         final Vector2D v = Vector2D.of(1, 2);
diff --git 
a/commons-geometry-spherical/src/test/java/org/apache/commons/geometry/spherical/oned/Point1STest.java
 
b/commons-geometry-spherical/src/test/java/org/apache/commons/geometry/spherical/oned/Point1STest.java
index e7c0284..f9772c1 100644
--- 
a/commons-geometry-spherical/src/test/java/org/apache/commons/geometry/spherical/oned/Point1STest.java
+++ 
b/commons-geometry-spherical/src/test/java/org/apache/commons/geometry/spherical/oned/Point1STest.java
@@ -209,6 +209,25 @@ public class Point1STest {
     }
 
     @Test
+    public void testEqualsAndHashCode_signedZeroConsistency() {
+        // arrange
+        final Point1S a = Point1S.of(0.0);
+        final Point1S b = Point1S.of(-0.0);
+        final Point1S c = Point1S.of(0.0);
+        final Point1S d = Point1S.of(-0.0);
+
+        // act/assert
+        Assert.assertFalse(a.equals(b));
+        Assert.assertNotEquals(a.hashCode(), b.hashCode());
+
+        Assert.assertTrue(a.equals(c));
+        Assert.assertEquals(a.hashCode(), c.hashCode());
+
+        Assert.assertTrue(b.equals(d));
+        Assert.assertEquals(b.hashCode(), d.hashCode());
+    }
+
+    @Test
     public void testEq() {
         // arrange
         final DoublePrecisionContext highPrecision = new 
EpsilonDoublePrecisionContext(1e-10);

Reply via email to