Author: Armin Rigo <[email protected]>
Branch: numpypy-complex2
Changeset: r57906:3378cc2fde22
Date: 2012-10-08 14:02 +0200
http://bitbucket.org/pypy/pypy/changeset/3378cc2fde22/
Log: (fijal around, arigo)
- fix c_pow() to return (nan+nanj) instead of raising an RPython
ValueError in some cases
- reuse the logic from pypy.rlib.rcomplex from complexobject.py
diff --git a/pypy/objspace/std/complexobject.py
b/pypy/objspace/std/complexobject.py
--- a/pypy/objspace/std/complexobject.py
+++ b/pypy/objspace/std/complexobject.py
@@ -8,7 +8,7 @@
from pypy.rlib.rbigint import rbigint
from pypy.rlib.rfloat import (
formatd, DTSF_STR_PRECISION, isinf, isnan, copysign)
-from pypy.rlib import jit
+from pypy.rlib import jit, rcomplex
from pypy.rlib.rarithmetic import intmask
import math
@@ -63,6 +63,9 @@
""" representation for debugging purposes """
return "<W_ComplexObject(%f,%f)>" % (w_self.realval, w_self.imagval)
+ def as_tuple(self):
+ return (self.realval, self.imagval)
+
def sub(self, other):
return W_ComplexObject(self.realval - other.realval,
self.imagval - other.imagval)
@@ -73,31 +76,8 @@
return W_ComplexObject(r, i)
def div(self, other):
- r1, i1 = self.realval, self.imagval
- r2, i2 = other.realval, other.imagval
- if r2 < 0:
- abs_r2 = - r2
- else:
- abs_r2 = r2
- if i2 < 0:
- abs_i2 = - i2
- else:
- abs_i2 = i2
- if abs_r2 >= abs_i2:
- if abs_r2 == 0.0:
- raise ZeroDivisionError
- else:
- ratio = i2 / r2
- denom = r2 + i2 * ratio
- rr = (r1 + i1 * ratio) / denom
- ir = (i1 - r1 * ratio) / denom
- else:
- ratio = r2 / i2
- denom = r2 * ratio + i2
- assert i2 != 0.0
- rr = (r1 * ratio + i1) / denom
- ir = (i1 * ratio - r1) / denom
- return W_ComplexObject(rr,ir)
+ rr, ir = rcomplex.c_div(self.as_tuple(), other.as_tuple())
+ return W_ComplexObject(rr, ir)
def divmod(self, space, other):
space.warn(
@@ -111,24 +91,7 @@
return (W_ComplexObject(div, 0), w_mod)
def pow(self, other):
- r1, i1 = self.realval, self.imagval
- r2, i2 = other.realval, other.imagval
- if r2 == 0.0 and i2 == 0.0:
- rr, ir = 1, 0
- elif r1 == 0.0 and i1 == 0.0:
- if i2 != 0.0 or r2 < 0.0:
- raise ZeroDivisionError
- rr, ir = (0.0, 0.0)
- else:
- vabs = math.hypot(r1,i1)
- len = math.pow(vabs,r2)
- at = math.atan2(i1,r1)
- phase = at * r2
- if i2 != 0.0:
- len /= math.exp(at * i2)
- phase += i2 * math.log(vabs)
- rr = len * math.cos(phase)
- ir = len * math.sin(phase)
+ rr, ir = rcomplex.c_pow(self.as_tuple(), other.as_tuple())
return W_ComplexObject(rr, ir)
def pow_small_int(self, n):
diff --git a/pypy/objspace/std/test/test_complexobject.py
b/pypy/objspace/std/test/test_complexobject.py
--- a/pypy/objspace/std/test/test_complexobject.py
+++ b/pypy/objspace/std/test/test_complexobject.py
@@ -220,6 +220,9 @@
b = 5.1+2.3j
raises(ValueError, pow, a, b, 0)
+ b = complex(float('inf'), 0.0) ** complex(10., 3.)
+ assert repr(b) == "(nan+nanj)"
+
def test_boolcontext(self):
from random import random
for i in xrange(100):
diff --git a/pypy/rlib/rcomplex.py b/pypy/rlib/rcomplex.py
--- a/pypy/rlib/rcomplex.py
+++ b/pypy/rlib/rcomplex.py
@@ -86,8 +86,12 @@
if i2 != 0.0:
len /= math.exp(at * i2)
phase += i2 * math.log(vabs)
- rr = len * math.cos(phase)
- ir = len * math.sin(phase)
+ try:
+ rr = len * math.cos(phase)
+ ir = len * math.sin(phase)
+ except ValueError:
+ rr = NAN
+ ir = NAN
return (rr, ir)
#unary
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit