[pypy-svn] pypy cmath: (lac, arigo)
arigo
commits-noreply at bitbucket.org
Mon Jan 17 15:45:45 CET 2011
Author: Armin Rigo <arigo at tunes.org>
Branch: cmath
Changeset: r40769:0e06e114ac1a
Date: 2011-01-17 15:45 +0100
http://bitbucket.org/pypy/pypy/changeset/0e06e114ac1a/
Log: (lac, arigo)
Finish the implementation of c_sqrt(). Yay!
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
@@ -1,8 +1,19 @@
from __future__ import with_statement
from pypy.conftest import gettestobjspace
+from pypy.rlib.rarithmetic import copysign
import os
+def test_special_values():
+ from pypy.module.cmath.special_value import sqrt_special_values
+ assert len(sqrt_special_values) == 7
+ assert len(sqrt_special_values[4]) == 7
+ assert isinstance(sqrt_special_values[5][1], tuple)
+ assert sqrt_special_values[5][1][0] == 1e200 * 1e200
+ assert sqrt_special_values[5][1][1] == -0.
+ assert copysign(1., sqrt_special_values[5][1][1]) == -1.
+
+
class AppTestCMath:
def setup_class(cls):
cls.space = gettestobjspace(usemodules=['cmath'])
@@ -23,6 +34,9 @@
z = cmath.sqrt((dbl_min * 0.00000000000001) + 0j)
assert abs(z.real - 1.49107189843e-161) < 1e-170
assert z.imag == 0.0
+ z = cmath.sqrt(1e200*1e200 - 10j)
+ assert math.isinf(z.real) and z.real > 0.0
+ assert z.imag == 0.0 and math.copysign(1., z.imag) == -1.
def test_acos(self):
import cmath
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
@@ -3,6 +3,8 @@
from pypy.interpreter.gateway import ObjSpace, W_Root
from pypy.module.cmath import Module
from pypy.module.cmath.constant import DBL_MIN, CM_SCALE_UP, CM_SCALE_DOWN
+from pypy.module.cmath.special_value import isfinite, special_type
+from pypy.module.cmath.special_value import sqrt_special_values
def unaryfn(name):
@@ -44,7 +46,8 @@
# x and y by a sufficiently large power of 2 to ensure that x and y
# are normal.
- #XXX SPECIAL_VALUE
+ if not isfinite(x) or not isfinite(y):
+ return sqrt_special_values[special_type(x)][special_type(y)]
if x == 0. and y == 0.:
return (0., y)
diff --git a/pypy/module/cmath/special_value.py b/pypy/module/cmath/special_value.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/cmath/special_value.py
@@ -0,0 +1,77 @@
+import math
+from pypy.rlib.rarithmetic import isnan, isinf, copysign
+
+# code to deal with special values (infinities, NaNs, ...)
+#
+# The special types can be:
+ST_NINF = 0 # negative infinity
+ST_NEG = 1 # negative finite number (nonzero)
+ST_NZERO = 2 # -0.
+ST_PZERO = 3 # +0.
+ST_POS = 4 # positive finite number (nonzero)
+ST_PINF = 5 # positive infinity
+ST_NAN = 6 # Not a Number
+
+def special_type(d):
+ if isnan(d):
+ return ST_NAN
+ elif isinf(d):
+ if d > 0.0:
+ return ST_PINF
+ else:
+ return ST_NINF
+ else:
+ if d != 0.0:
+ if d > 0.0:
+ return ST_POS
+ else:
+ return ST_NEG
+ else:
+ if copysign(1., d) == 1.:
+ return ST_PZERO
+ else:
+ return ST_NZERO
+
+def isfinite(d):
+ return not isinf(d) and not isnan(d)
+
+
+P = math.pi
+P14 = 0.25 * math.pi
+P12 = 0.5 * math.pi
+P34 = 0.75 * math.pi
+INF = 1e200 * 1e200
+N = INF / INF
+U = -9.5426319407711027e33 # unlikely value, used as placeholder
+
+def build_table(lst):
+ table = []
+ assert len(lst) == 49
+ it = iter(lst)
+ for j in range(7):
+ row = []
+ for i in range(7):
+ (x, y) = it.next()
+ row.append((x, y))
+ table.append(row)
+ return table
+
+##acos_special_values = build_table([
+## C(P34,INF),C(P,INF), C(P,INF), C(P,-INF), C(P,-INF), C(P34,-INF),C(N,INF),
+## C(P12,INF),C(U,U), C(U,U), C(U,U), C(U,U), C(P12,-INF),C(N,N),
+## C(P12,INF),C(U,U), C(P12,0.),C(P12,-0.),C(U,U), C(P12,-INF),C(P12,N),
+## C(P12,INF),C(U,U), C(P12,0.),C(P12,-0.),C(U,U), C(P12,-INF),C(P12,N),
+## C(P12,INF),C(U,U), C(U,U), C(U,U), C(U,U), C(P12,-INF),C(N,N),
+## C(P14,INF),C(0.,INF),C(0.,INF),C(0.,-INF),C(0.,-INF),C(P14,-INF),C(N,INF),
+## C(N,INF), C(N,N), C(N,N), C(N,N), C(N,N), C(N,-INF), C(N,N)
+## ])
+
+sqrt_special_values = build_table([
+ (INF,-INF), (0.,-INF), (0.,-INF), (0.,INF), (0.,INF), (INF,INF), (N,INF),
+ (INF,-INF), (U,U), (U,U), (U,U), (U,U), (INF,INF), (N,N),
+ (INF,-INF), (U,U), (0.,-0.), (0.,0.), (U,U), (INF,INF), (N,N),
+ (INF,-INF), (U,U), (0.,-0.), (0.,0.), (U,U), (INF,INF), (N,N),
+ (INF,-INF), (U,U), (U,U), (U,U), (U,U), (INF,INF), (N,N),
+ (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),
+ ])
More information about the Pypy-commit
mailing list