[pypy-svn] pypy cmath: (david, lac, arigo)
arigo
commits-noreply at bitbucket.org
Tue Jan 18 13:02:52 CET 2011
Author: Armin Rigo <arigo at tunes.org>
Branch: cmath
Changeset: r40841:b621137f9070
Date: 2011-01-18 12:23 +0100
http://bitbucket.org/pypy/pypy/changeset/b621137f9070/
Log: (david, lac, arigo)
Fix for translating -0.0, avoiding confusion with 0.0 in a couple of
places.
diff --git a/pypy/translator/c/test/test_genc.py b/pypy/translator/c/test/test_genc.py
--- a/pypy/translator/c/test/test_genc.py
+++ b/pypy/translator/c/test/test_genc.py
@@ -269,25 +269,40 @@
res = f1(3)
assert res == 1.5
-def test_nan():
+def test_nan_and_special_values():
from pypy.translator.c.primitive import isnan, isinf
+ from pypy.rlib.rarithmetic import copysign
inf = 1e300 * 1e300
assert isinf(inf)
nan = inf/inf
assert isnan(nan)
- l = [nan]
- def f():
- return nan
- f1 = compile(f, [])
- res = f1()
- assert isnan(res)
+ for value, checker in [
+ (inf, lambda x: isinf(x) and x > 0.0),
+ (-inf, lambda x: isinf(x) and x < 0.0),
+ (nan, isnan),
+ (0.0, lambda x: not x and copysign(1., x) == 1.),
+ (-0.0, lambda x: not x and copysign(1., x) == -1.),
+ ]:
+ def f():
+ return value
+ f1 = compile(f, [])
+ res = f1()
+ assert checker(res)
- def g(x):
- return l[x]
- g2 = compile(g, [int])
- res = g2(0)
- assert isnan(res)
+ l = [value]
+ def g(x):
+ return l[x]
+ g2 = compile(g, [int])
+ res = g2(0)
+ assert checker(res)
+
+ l2 = [(-value, -value), (value, value)]
+ def h(x):
+ return l2[x][1]
+ h3 = compile(h, [int])
+ res = h3(1)
+ assert checker(res)
def test_prebuilt_instance_with_dict():
class A:
diff --git a/pypy/annotation/model.py b/pypy/annotation/model.py
--- a/pypy/annotation/model.py
+++ b/pypy/annotation/model.py
@@ -163,11 +163,16 @@
immutable = True
def __eq__(self, other):
- # NaN unpleasantness.
if (type(self) is SomeFloat and type(other) is SomeFloat and
- self.is_constant() and other.is_constant() and
- isnan(self.const) and isnan(other.const)):
- return True
+ self.is_constant() and other.is_constant()):
+ # NaN unpleasantness.
+ if isnan(self.const) and isnan(other.const):
+ return True
+ # 0.0 vs -0.0 unpleasantness.
+ if not self.const and not other.const:
+ from pypy.rlib.rarithmetic import copysign
+ return copysign(1., self.const) == copysign(1., other.const)
+ #
return super(SomeFloat, self).__eq__(other)
def can_be_none(self):
diff --git a/pypy/tool/uid.py b/pypy/tool/uid.py
--- a/pypy/tool/uid.py
+++ b/pypy/tool/uid.py
@@ -38,26 +38,36 @@
key in dictionaries. This is based on id() for mutable objects and on
real hash/compare for immutable ones.
"""
- __slots__ = ["key", "value"]
+ __slots__ = ["_key", "value"]
def __init__(self, value):
self.value = value # a concrete value
# try to be smart about constant mutable or immutable values
key = type(self.value), self.value # to avoid confusing e.g. 0 and 0.0
+ #
+ # we also have to avoid confusing 0.0 and -0.0 (needed e.g. for
+ # translating the cmath module)
+ if key[0] is float and not self.value:
+ from pypy.rlib.rarithmetic import copysign
+ if copysign(1., self.value) == 1.: # +0.0
+ key = (float, "+0.0")
+ else:
+ key = (float, "-0.0")
+ #
try:
hash(key)
except TypeError:
key = id(self.value)
- self.key = key
+ self._key = key
def __eq__(self, other):
- return self.__class__ is other.__class__ and self.key == other.key
+ return self.__class__ is other.__class__ and self._key == other._key
def __ne__(self, other):
return not (self == other)
def __hash__(self):
- return hash(self.key)
+ return hash(self._key)
def __repr__(self):
return '(%s)' % (self,)
More information about the Pypy-commit
mailing list