[pypy-svn] pypy cmath: (lac, arigo)

arigo commits-noreply at bitbucket.org
Mon Jan 17 18:00:52 CET 2011


Author: Armin Rigo <arigo at tunes.org>
Branch: cmath
Changeset: r40788:3c84bb30724d
Date: 2011-01-17 18:00 +0100
http://bitbucket.org/pypy/pypy/changeset/3c84bb30724d/

Log:	(lac, arigo)

	exp().

diff --git a/pypy/module/cmath/__init__.py b/pypy/module/cmath/__init__.py
--- a/pypy/module/cmath/__init__.py
+++ b/pypy/module/cmath/__init__.py
@@ -14,6 +14,7 @@
             "If the base not specified, returns the natural logarithm "
             "(base e) of x."),
     'log10': "Return the base-10 logarithm of x.",
+    'exp': "Return the exponential value e**x.",
     }
 
 

diff --git a/pypy/module/cmath/test/test_cmath.py b/pypy/module/cmath/test/test_cmath.py
--- a/pypy/module/cmath/test/test_cmath.py
+++ b/pypy/module/cmath/test/test_cmath.py
@@ -153,16 +153,15 @@
                 raise AssertionError('ValueError not raised in test '
                                      '%s: %s(complex(%r, %r))' % (id, fn,
                                                                   ar, ai))
-
         if 'overflow' in flags:
             try:
-                actual = function(arg)
+                actual = function(*arg)
             except OverflowError:
                 continue
             else:
-                self.fail('OverflowError not raised in test '
-                      '{}: {}(complex({!r}, {!r}))'.format(id, fn, ar, ai))
-
+                raise AssertionError('OverflowError not raised in test '
+                                     '%s: %s(complex(%r, %r))' % (id, fn,
+                                                                  ar, ai))
         actual = function(*arg)
 
         if 'ignore-real-sign' in flags:

diff --git a/pypy/module/cmath/interp_cmath.py b/pypy/module/cmath/interp_cmath.py
--- a/pypy/module/cmath/interp_cmath.py
+++ b/pypy/module/cmath/interp_cmath.py
@@ -1,19 +1,21 @@
 import math
 from math import fabs
-from pypy.rlib.rarithmetic import copysign, asinh, log1p
+from pypy.rlib.rarithmetic import copysign, asinh, log1p, isinf
 from pypy.interpreter.gateway import ObjSpace, W_Root, NoneNotWrapped
 from pypy.module.cmath import Module, names_and_docstrings
 from pypy.module.cmath.constant import DBL_MIN, CM_SCALE_UP, CM_SCALE_DOWN
 from pypy.module.cmath.constant import CM_LARGE_DOUBLE, DBL_MANT_DIG
 from pypy.module.cmath.constant import M_LN2, M_LN10
 from pypy.module.cmath.constant import CM_SQRT_LARGE_DOUBLE, CM_SQRT_DBL_MIN
-from pypy.module.cmath.special_value import isfinite, special_type
+from pypy.module.cmath.constant import CM_LOG_LARGE_DOUBLE
+from pypy.module.cmath.special_value import isfinite, special_type, INF
 from pypy.module.cmath.special_value import sqrt_special_values
 from pypy.module.cmath.special_value import acos_special_values
 from pypy.module.cmath.special_value import acosh_special_values
 from pypy.module.cmath.special_value import asinh_special_values
 from pypy.module.cmath.special_value import atanh_special_values
 from pypy.module.cmath.special_value import log_special_values
+from pypy.module.cmath.special_value import exp_special_values
 
 
 def unaryfn(c_func):
@@ -284,3 +286,36 @@
 def c_log10(x, y):
     rx, ry = c_log(x, y)
     return (rx / M_LN10, ry / M_LN10)
+
+
+ at unaryfn
+def c_exp(x, y):
+    if not isfinite(x) or not isfinite(y):
+        if isinf(x) and isfinite(y) and y != 0.:
+            if x > 0:
+                real = copysign(INF, math.cos(y))
+                imag = copysign(INF, math.sin(y))
+            else:
+                real = copysign(0., math.cos(y))
+                imag = copysign(0., math.sin(y))
+            r = (real, imag)
+        else:
+            r = exp_special_values[special_type(x)][special_type(y)]
+
+        # need to raise ValueError if y is +/- infinity and x is not
+        # a NaN and not -infinity
+        if isinf(y) and (isfinite(x) or (isinf(x) and x > 0)):
+            raise ValueError("math domain error")
+        return r
+
+    if x > CM_LOG_LARGE_DOUBLE:
+        l = math.exp(x-1.)
+        real = l * math.cos(y) * math.e
+        imag = l * math.sin(y) * math.e
+    else:
+        l = math.exp(x)
+        real = l * math.cos(y)
+        imag = l * math.sin(y)
+    if isinf(real) or isinf(imag):
+        raise OverflowError("math range error")
+    return real, imag

diff --git a/pypy/module/cmath/special_value.py b/pypy/module/cmath/special_value.py
--- a/pypy/module/cmath/special_value.py
+++ b/pypy/module/cmath/special_value.py
@@ -115,3 +115,13 @@
     (INF,-INF), (INF,-0.), (INF,-0.), (INF,0.), (INF,0.), (INF,INF), (INF,N),
     (INF,-INF), (N,N),     (N,N),     (N,N),    (N,N),    (INF,INF), (N,N),
     ])
+
+exp_special_values = build_table([
+    (0.,0.), (U,U), (0.,-0.),  (0.,0.),  (U,U), (0.,0.), (0.,0.),
+    (N,N),   (U,U), (U,U),     (U,U),    (U,U), (N,N),   (N,N),
+    (N,N),   (U,U), (1.,-0.),  (1.,0.),  (U,U), (N,N),   (N,N),
+    (N,N),   (U,U), (1.,-0.),  (1.,0.),  (U,U), (N,N),   (N,N),
+    (N,N),   (U,U), (U,U),     (U,U),    (U,U), (N,N),   (N,N),
+    (INF,N), (U,U), (INF,-0.), (INF,0.), (U,U), (INF,N), (INF,N),
+    (N,N),   (N,N), (N,-0.),   (N,0.),   (N,N), (N,N),   (N,N),
+    ])


More information about the Pypy-commit mailing list