commons-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From l..@apache.org
Subject svn commit: r769867 - in /commons/proper/math/trunk/src: java/org/apache/commons/math/util/MathUtils.java site/xdoc/changes.xml test/org/apache/commons/math/util/MathUtilsTest.java
Date Wed, 29 Apr 2009 18:34:00 GMT
Author: luc
Date: Wed Apr 29 18:33:59 2009
New Revision: 769867

URL: http://svn.apache.org/viewvc?rev=769867&view=rev
Log:
Added an utility equality method between double numbers using tolerance
in ulps (Units in Last Position) 
JIRA: MATH-264

Modified:
    commons/proper/math/trunk/src/java/org/apache/commons/math/util/MathUtils.java
    commons/proper/math/trunk/src/site/xdoc/changes.xml
    commons/proper/math/trunk/src/test/org/apache/commons/math/util/MathUtilsTest.java

Modified: commons/proper/math/trunk/src/java/org/apache/commons/math/util/MathUtils.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/java/org/apache/commons/math/util/MathUtils.java?rev=769867&r1=769866&r2=769867&view=diff
==============================================================================
--- commons/proper/math/trunk/src/java/org/apache/commons/math/util/MathUtils.java (original)
+++ commons/proper/math/trunk/src/java/org/apache/commons/math/util/MathUtils.java Wed Apr
29 18:33:59 2009
@@ -59,6 +59,9 @@
     /** 2 π. */
     private static final double TWO_PI = 2 * Math.PI;
 
+    private static final int NAN_GAP = 4 * 1024 * 1024;
+    private static final long SGN_MASK = 0x8000000000000000L;
+
     /**
      * Private Constructor
      */
@@ -407,6 +410,39 @@
     }
     
     /**
+     * Returns true iff both arguments are equal or within the range of allowed
+     * error (inclusive).
+     * Adapted from <a
+     * href="http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm">
+     * Bruce Dawson</a>
+     *
+     * @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 less than {@code maxUlps} floating
+     * point values between {@code x} and {@code y}
+     */
+    public static boolean equals(double x, double y, int maxUlps) {
+        // Check that "maxUlps" is non-negative and small enough so that the
+        // default NAN won't compare as equal to anything.
+        assert maxUlps > 0 && maxUlps < NAN_GAP;
+
+        long xInt = Double.doubleToLongBits(x);
+        long yInt = Double.doubleToLongBits(y);
+
+        // Make lexicographically ordered as a two's-complement integer.
+        if (xInt < 0) {
+            xInt = SGN_MASK - xInt;
+        }
+        if (yInt < 0) {
+            yInt = SGN_MASK - yInt;
+        }
+
+        return Math.abs(xInt - yInt) <= maxUlps;
+    }
+
+    /**
      * Returns true iff both arguments are null or have same dimensions
      * and all their elements are {@link #equals(double,double) equals}
      * 

Modified: commons/proper/math/trunk/src/site/xdoc/changes.xml
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/site/xdoc/changes.xml?rev=769867&r1=769866&r2=769867&view=diff
==============================================================================
--- commons/proper/math/trunk/src/site/xdoc/changes.xml (original)
+++ commons/proper/math/trunk/src/site/xdoc/changes.xml Wed Apr 29 18:33:59 2009
@@ -39,6 +39,10 @@
   </properties>
   <body>
     <release version="2.0" date="TBD" description="TBD">
+      <action dev="luc" type="fix" issue="MATH-264" due-to="Gilles Sadowski">
+        Added an utility equality method between double numbers using tolerance
+        in ulps (Units in Last Position) 
+      </action>
       <action dev="luc" type="add" >
         Added support for any type of field in linear algebra (FielxMatrix, FieldVector,
         FieldLUDecomposition)

Modified: commons/proper/math/trunk/src/test/org/apache/commons/math/util/MathUtilsTest.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/org/apache/commons/math/util/MathUtilsTest.java?rev=769867&r1=769866&r2=769867&view=diff
==============================================================================
--- commons/proper/math/trunk/src/test/org/apache/commons/math/util/MathUtilsTest.java (original)
+++ commons/proper/math/trunk/src/test/org/apache/commons/math/util/MathUtilsTest.java Wed
Apr 29 18:33:59 2009
@@ -353,6 +353,31 @@
         assertFalse(MathUtils.equals(153.0000, 153.0625, .0624));
         assertFalse(MathUtils.equals(152.9374, 153.0000, .0625));
     }
+
+    public void testEqualsWithAllowedUlps() {
+        assertTrue(MathUtils.equals(153, 153, 1));
+
+        assertTrue(MathUtils.equals(153, 153.00000000000003, 1));
+        assertFalse(MathUtils.equals(153, 153.00000000000006, 1));
+        assertTrue(MathUtils.equals(153, 152.99999999999997, 1));
+        assertFalse(MathUtils.equals(153, 152.99999999999994, 1));
+        
+        assertTrue(MathUtils.equals(-128, -127.99999999999999, 1));
+        assertFalse(MathUtils.equals(-128, -127.99999999999997, 1));
+        assertTrue(MathUtils.equals(-128, -128.00000000000003, 1));
+        assertFalse(MathUtils.equals(-128, -128.00000000000006, 1));
+
+        assertTrue(MathUtils.equals(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY, 1));
+        assertTrue(MathUtils.equals(Double.MAX_VALUE, Double.POSITIVE_INFINITY, 1));
+
+        assertTrue(MathUtils.equals(Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY, 1));
+        assertTrue(MathUtils.equals(-Double.MAX_VALUE, Double.NEGATIVE_INFINITY, 1));
+
+
+        assertTrue(MathUtils.equals(Double.NaN, Double.NaN, 1));
+
+        assertFalse(MathUtils.equals(Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY,
100000));
+    }
     
     public void testArrayEquals() {
         assertFalse(MathUtils.equals(new double[] { 1d }, null));



Mime
View raw message