[Jython-checkins] jython: Rectify cmath.rect() corner-cases.

jeff.allen jython-checkins at python.org
Tue Jan 20 23:07:17 CET 2015


https://hg.python.org/jython/rev/53f2008ed99f
changeset:   7551:53f2008ed99f
user:        Jeff Allen <ja.py at farowl.co.uk>
date:        Sun Jan 18 23:43:35 2015 +0000
summary:
  Rectify cmath.rect() corner-cases.

files:
  src/org/python/modules/cmath.java |  58 +++++++++++++-----
  1 files changed, 42 insertions(+), 16 deletions(-)


diff --git a/src/org/python/modules/cmath.java b/src/org/python/modules/cmath.java
--- a/src/org/python/modules/cmath.java
+++ b/src/org/python/modules/cmath.java
@@ -625,25 +625,42 @@
         return new PyTuple(new PyFloat(r), new PyFloat(phi));
     }
 
+    /**
+     * Return the complex number x with polar coordinates r and phi. Equivalent to
+     * <code>r * (math.cos(phi) + math.sin(phi)*1j)</code>.
+     *
+     * @param r radius
+     * @param phi angle
+     * @return
+     */
     public static PyComplex rect(double r, double phi) {
-        // Handle various edge cases
+        double x, y;
+
         if (Double.isInfinite(r) && (Double.isInfinite(phi) || Double.isNaN(phi))) {
-            return new PyComplex(Double.POSITIVE_INFINITY, Double.NaN);
+            x = Double.POSITIVE_INFINITY;
+            y = Double.NaN;
+
+        } else if (phi == 0.0) {
+            // cos(phi)=1, sin(phi)=phi: finesse oddball r in computing y, but not x.
+            x = r;
+            if (Double.isNaN(r)) {
+                y = phi;
+            } else if (Double.isInfinite(r)) {
+                y = phi * Math.copySign(1., r);
+            } else {
+                y = phi * r;
+            }
+
+        } else if (r == 0.0 && (Double.isInfinite(phi) || Double.isNaN(phi))) {
+            // Ignore any problems (inf, nan) with phi
+            x = y = 0.;
+
+        } else {
+            // Text-book case, using the trig functions.
+            x = r * Math.cos(phi);
+            y = r * Math.sin(phi);
         }
-        if (phi == 0.0) { // NB this test will succeed if phi is 0.0 or -0.0
-            if (Double.isNaN(r)) {
-                return new PyComplex(Double.NaN, 0.0);
-            } else if (r == Double.POSITIVE_INFINITY) {
-                return new PyComplex(r, phi);
-            } else if (r == Double.NEGATIVE_INFINITY) {
-                return new PyComplex(r, -phi);
-            }
-        }
-        if (r == 0.0 && (Double.isInfinite(phi) || Double.isNaN(phi))) {
-            return new PyComplex(0.0, 0.0);
-        }
-
-        return new PyComplex(r * Math.cos(phi), r * Math.sin(phi));
+        return exceptNaN(new PyComplex(x, y), r, phi);
     }
 
     /**
@@ -1128,6 +1145,15 @@
         }
     }
 
+    private static PyComplex exceptNaN(PyComplex result, double a, double b) throws PyException {
+        if ((Double.isNaN(result.real) || Double.isNaN(result.imag))
+                && !(Double.isNaN(a) || Double.isNaN(b))) {
+            throw math.mathDomainError();
+        } else {
+            return result;
+        }
+    }
+
     /**
      * Turn an infinite result into a thrown <code>OverflowError</code>, a math range error, if the
      * original argument was not itself infinite. A <code>PyComplex</code> is infinite if either

-- 
Repository URL: https://hg.python.org/jython


More information about the Jython-checkins mailing list