Repository: commons-complex
Updated Branches:
  refs/heads/master 1aba3c8ca -> 7524db548


[COMPLEX-1] Fix equals methods in Complex and Quaternion by copying over 
Precision from commons-math.  Made Precision package protected and removed 
parts not used by code currently in commons-complex.  This fixes ComplexTest 
and QuaternionTest unit tests.
Fix RootsOfUnityTest by changing test methods to expect the correct exception 
class.

Project: http://git-wip-us.apache.org/repos/asf/commons-complex/repo
Commit: http://git-wip-us.apache.org/repos/asf/commons-complex/commit/f7cca80f
Tree: http://git-wip-us.apache.org/repos/asf/commons-complex/tree/f7cca80f
Diff: http://git-wip-us.apache.org/repos/asf/commons-complex/diff/f7cca80f

Branch: refs/heads/master
Commit: f7cca80f4a6913f22829ad5dfcebd980ce5289cd
Parents: 1aba3c8
Author: Ray DeCampo <[email protected]>
Authored: Fri Jan 6 17:35:51 2017 -0500
Committer: Ray DeCampo <[email protected]>
Committed: Fri Jan 6 17:35:51 2017 -0500

----------------------------------------------------------------------
 .../org/apache/commons/complex/Complex.java     |  12 +-
 .../org/apache/commons/complex/Precision.java   | 128 +++++++++++++++++++
 .../org/apache/commons/complex/Quaternion.java  |  27 +---
 .../commons/complex/RootsOfUnityTest.java       |  13 +-
 4 files changed, 145 insertions(+), 35 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/commons-complex/blob/f7cca80f/src/main/java/org/apache/commons/complex/Complex.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/complex/Complex.java 
b/src/main/java/org/apache/commons/complex/Complex.java
index 8f289e2..937820d 100644
--- a/src/main/java/org/apache/commons/complex/Complex.java
+++ b/src/main/java/org/apache/commons/complex/Complex.java
@@ -363,8 +363,8 @@ public class Complex implements Serializable  {
      * @since 3.3
      */
     public static boolean equals(Complex x, Complex y, int maxUlps) {
-        return equals(x.real, y.real) &&
-            equals(x.imaginary, y.imaginary);
+        return Precision.equals(x.real, y.real, maxUlps) &&
+            Precision.equals(x.imaginary, y.imaginary, maxUlps);
     }
 
     /**
@@ -397,8 +397,8 @@ public class Complex implements Serializable  {
      * @since 3.3
      */
     public static boolean equals(Complex x, Complex y, double eps) {
-        return equals(x.real, y.real) &&
-            equals(x.imaginary, y.imaginary);
+        return Precision.equals(x.real, y.real, eps) &&
+            Precision.equals(x.imaginary, y.imaginary, eps);
     }
 
     /**
@@ -418,8 +418,8 @@ public class Complex implements Serializable  {
      */
     public static boolean equalsWithRelativeTolerance(Complex x, Complex y,
                                                       double eps) {
-        return equalsWithRelativeTolerance(x.real, y.real, eps) &&
-            equalsWithRelativeTolerance(x.imaginary, y.imaginary, eps);
+        return Precision.equalsWithRelativeTolerance(x.real, y.real, eps) &&
+            Precision.equalsWithRelativeTolerance(x.imaginary, y.imaginary, 
eps);
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/commons-complex/blob/f7cca80f/src/main/java/org/apache/commons/complex/Precision.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/complex/Precision.java 
b/src/main/java/org/apache/commons/complex/Precision.java
new file mode 100644
index 0000000..77f5048
--- /dev/null
+++ b/src/main/java/org/apache/commons/complex/Precision.java
@@ -0,0 +1,128 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.complex;
+
+/**
+ * Utilities for comparing numbers.
+ */
+class Precision {
+    /** Offset to order signed double numbers lexicographically. */
+    private static final long SGN_MASK = 0x8000000000000000L;
+    /** Positive zero bits. */
+    private static final long POSITIVE_ZERO_DOUBLE_BITS = 
Double.doubleToRawLongBits(+0.0);
+    /** Negative zero bits. */
+    private static final long NEGATIVE_ZERO_DOUBLE_BITS = 
Double.doubleToRawLongBits(-0.0);
+
+    /**
+     * Private constructor.
+     */
+    private Precision() {}
+
+    /**
+     * Returns {@code true} if there is no double value strictly between the
+     * arguments or the difference between them is within the range of allowed
+     * error (inclusive). Returns {@code false} if either of the arguments
+     * is NaN.
+     *
+     * @param x First value.
+     * @param y Second value.
+     * @param eps Amount of allowed absolute error.
+     * @return {@code true} if the values are two adjacent floating point
+     * numbers or they are within range of each other.
+     */
+    public static boolean equals(double x, double y, double eps) {
+        return equals(x, y, 1) || Math.abs(y - x) <= eps;
+    }
+
+    /**
+     * Returns {@code true} if there is no double value strictly between the
+     * arguments or the relative difference between them is less than or equal
+     * to the given tolerance. Returns {@code false} if either of the arguments
+     * is NaN.
+     *
+     * @param x First value.
+     * @param y Second value.
+     * @param eps Amount of allowed relative error.
+     * @return {@code true} if the values are two adjacent floating point
+     * numbers or they are within range of each other.
+     */
+    public static boolean equalsWithRelativeTolerance(double x, double y, 
double eps) {
+        if (equals(x, y, 1)) {
+            return true;
+        }
+
+        final double absoluteMax = Math.max(Math.abs(x), Math.abs(y));
+        final double relativeDifference = Math.abs((x - y) / absoluteMax);
+
+        return relativeDifference <= eps;
+    }
+
+    /**
+     * Returns true if the arguments are equal or within the range of allowed
+     * error (inclusive).
+     * <p>
+     * Two float numbers are considered equal if there are {@code (maxUlps - 
1)}
+     * (or fewer) floating point numbers between them, i.e. two adjacent
+     * floating point numbers are considered equal.
+     * </p>
+     * <p>
+     * Adapted from <a
+     * 
href="http://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/";>
+     * Bruce Dawson</a>. Returns {@code false} if either of the arguments is 
NaN.
+     * </p>
+     *
+     * @param x first value
+     * @param y second value
+     * @param maxUlps {@code (maxUlps - 1)} is the number of floating point
+     * values between {@code x} and {@code y}.
+     * @return {@code true} if there are fewer than {@code maxUlps} floating
+     * point values between {@code x} and {@code y}.
+     */
+    public static boolean equals(final double x, final double y, final int 
maxUlps) {
+
+        final long xInt = Double.doubleToRawLongBits(x);
+        final long yInt = Double.doubleToRawLongBits(y);
+
+        final boolean isEqual;
+        if (((xInt ^ yInt) & SGN_MASK) == 0l) {
+            // number have same sign, there is no risk of overflow
+            isEqual = Math.abs(xInt - yInt) <= maxUlps;
+        } else {
+            // number have opposite signs, take care of overflow
+            final long deltaPlus;
+            final long deltaMinus;
+            if (xInt < yInt) {
+                deltaPlus  = yInt - POSITIVE_ZERO_DOUBLE_BITS;
+                deltaMinus = xInt - NEGATIVE_ZERO_DOUBLE_BITS;
+            } else {
+                deltaPlus  = xInt - POSITIVE_ZERO_DOUBLE_BITS;
+                deltaMinus = yInt - NEGATIVE_ZERO_DOUBLE_BITS;
+            }
+
+            if (deltaPlus > maxUlps) {
+                isEqual = false;
+            } else {
+                isEqual = deltaMinus <= (maxUlps - deltaPlus);
+            }
+
+        }
+
+        return isEqual && !Double.isNaN(x) && !Double.isNaN(y);
+
+    }
+}

http://git-wip-us.apache.org/repos/asf/commons-complex/blob/f7cca80f/src/main/java/org/apache/commons/complex/Quaternion.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/complex/Quaternion.java 
b/src/main/java/org/apache/commons/complex/Quaternion.java
index 7ce8a30..6fc29a3 100644
--- a/src/main/java/org/apache/commons/complex/Quaternion.java
+++ b/src/main/java/org/apache/commons/complex/Quaternion.java
@@ -306,10 +306,10 @@ public final class Quaternion implements Serializable {
      */
     public boolean equals(final Quaternion q,
                           final double eps) {
-        return equals(q0, q.getQ0(), eps) &&
-            equals(q1, q.getQ1(), eps) &&
-            equals(q2, q.getQ2(), eps) &&
-            equals(q3, q.getQ3(), eps);
+        return Precision.equals(q0, q.getQ0(), eps) &&
+            Precision.equals(q1, q.getQ1(), eps) &&
+            Precision.equals(q2, q.getQ2(), eps) &&
+            Precision.equals(q3, q.getQ3(), eps);
     }
 
     /**
@@ -321,7 +321,7 @@ public final class Quaternion implements Serializable {
      * {@code false} otherwise
      */
     public boolean isUnitQuaternion(double eps) {
-        return equals(getNorm(), 1d, eps);
+        return Precision.equals(getNorm(), 1d, eps);
     }
 
     /**
@@ -464,21 +464,4 @@ public final class Quaternion implements Serializable {
         return s.toString();
     }
 
-    /**
-     * Returns {@code true} if there is no double value strictly between the
-     * arguments or the difference between them is within the range of allowed
-     * error (inclusive). Returns {@code false} if either of the arguments
-     * is NaN.
-     *
-     * @param x First value.
-     * @param y Second value.
-     * @param eps Amount of allowed absolute error.
-     * @return {@code true} if the values are two adjacent floating point
-     * numbers or they are within range of each other.
-     */
-    private static boolean equals(double x, double y, double eps) {
-        return equals(x, y, 1) || Math.abs(y - x) <= eps;
-    }
-
-
 }

http://git-wip-us.apache.org/repos/asf/commons-complex/blob/f7cca80f/src/test/java/org/apache/commons/complex/RootsOfUnityTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/commons/complex/RootsOfUnityTest.java 
b/src/test/java/org/apache/commons/complex/RootsOfUnityTest.java
index 1929c21..81ab1a3 100644
--- a/src/test/java/org/apache/commons/complex/RootsOfUnityTest.java
+++ b/src/test/java/org/apache/commons/complex/RootsOfUnityTest.java
@@ -16,7 +16,6 @@
  */
 package org.apache.commons.complex;
 
-import org.apache.commons.complex.RootsOfUnity;
 import org.junit.Assert;
 import org.junit.Test;
 
@@ -27,20 +26,20 @@ import org.junit.Test;
  */
 public class RootsOfUnityTest {
 
-    @Test(expected = IllegalStateException.class)
-    public void testMathIllegalState1() {
+    @Test(expected = IllegalArgumentException.class)
+    public void testMathIllegalArgument1() {
         final RootsOfUnity roots = new RootsOfUnity();
         roots.getReal(0);
     }
 
-    @Test(expected = IllegalStateException.class)
-    public void testMathIllegalState2() {
+    @Test(expected = IllegalArgumentException.class)
+    public void testMathIllegalArgument2() {
         final RootsOfUnity roots = new RootsOfUnity();
         roots.getImaginary(0);
     }
 
-    @Test(expected = IllegalStateException.class)
-    public void testMathIllegalState3() {
+    @Test(expected = IllegalArgumentException.class)
+    public void testMathIllegalArgument3() {
         final RootsOfUnity roots = new RootsOfUnity();
         roots.isCounterClockWise();
     }

Reply via email to