[pypy-svn] r75796 - in pypy/branch/fast-forward/pypy/interpreter: astcompiler test

benjamin at codespeak.net benjamin at codespeak.net
Fri Jul 2 21:37:04 CEST 2010


Author: benjamin
Date: Fri Jul  2 21:37:01 2010
New Revision: 75796

Modified:
   pypy/branch/fast-forward/pypy/interpreter/astcompiler/assemble.py
   pypy/branch/fast-forward/pypy/interpreter/test/test_compiler.py
Log:
don't mix -0.0 and 0.0 in complex or float cases

Modified: pypy/branch/fast-forward/pypy/interpreter/astcompiler/assemble.py
==============================================================================
--- pypy/branch/fast-forward/pypy/interpreter/astcompiler/assemble.py	(original)
+++ pypy/branch/fast-forward/pypy/interpreter/astcompiler/assemble.py	Fri Jul  2 21:37:01 2010
@@ -8,6 +8,7 @@
 
 from pypy.interpreter.error import OperationError
 from pypy.rlib.objectmodel import we_are_translated
+from pypy.rlib import rarithmetic
 
 
 class Instruction(object):
@@ -209,7 +210,35 @@
         # To avoid confusing equal but separate types, we hash store the type of
         # the constant in the dictionary.
         if w_key is None:
-            w_key = space.newtuple([obj, space.type(obj)])
+            # We have to keep the difference between -0.0 and 0.0 floats.
+            w_type = space.type(obj)
+            if space.is_w(w_type, space.w_float):
+                val = space.float_w(obj)
+                if val == 0.0 and rarithmetic.copysign(1., val) < 0:
+                    w_key = space.newtuple([obj, space.w_float, space.w_None])
+                else:
+                    w_key = space.newtuple([obj, space.w_float])
+            elif space.is_w(w_type, space.w_complex):
+                w_real = space.getattr(obj, space.wrap("real"))
+                w_imag = space.getattr(obj, space.wrap("imag"))
+                real = space.float_w(w_real)
+                imag = space.float_w(w_imag)
+                real_negzero = (real == 0.0 and
+                                rarithmetic.copysign(1., real) < 0)
+                imag_negzero = (imag == 0.0 and
+                                rarithmetic.copysign(1., imag) < 0)
+                if real_negzero and imag_negzero:
+                    tup = [obj, space.w_complex, space.w_None, space.w_None,
+                           space.w_None]
+                elif imag_negzero:
+                    tup = [obj, space.w_complex, space.w_None, space.w_None]
+                elif real_negzero:
+                    tup = [obj, space.w_complex, space.w_None]
+                else:
+                    tup = [obj, space.w_complex]
+                w_key = space.newtuple(tup)
+            else:
+                w_key = space.newtuple([obj, w_type])
         w_len = space.finditem(self.w_consts, w_key)
         if w_len is None:
             w_len = space.len(self.w_consts)

Modified: pypy/branch/fast-forward/pypy/interpreter/test/test_compiler.py
==============================================================================
--- pypy/branch/fast-forward/pypy/interpreter/test/test_compiler.py	(original)
+++ pypy/branch/fast-forward/pypy/interpreter/test/test_compiler.py	Fri Jul  2 21:37:01 2010
@@ -704,6 +704,20 @@
         self.compiler = self.space.getexecutioncontext().compiler
 
 
+class AppTestCompiler:
+
+    def test_zeros_not_mixed(self):
+        import math
+        code = compile("x = -0.0; y = 0.0", "<test>", "exec")
+        consts = code.co_consts
+        assert len(consts) == 3
+        assert math.copysign(1, consts[0]) != math.copysign(1, consts[1])
+        ns = {}
+        exec "z1, z2 = 0j, -0j" in ns
+        assert math.atan2(ns["z1"].imag, -1.) == math.atan2(0., -1.)
+        assert math.atan2(ns["z2"].imag, -1.) == math.atan2(-0., -1.)
+
+
 ##class TestPythonAstCompiler(BaseTestCompiler):
 ##    def setup_method(self, method):
 ##        self.compiler = PythonAstCompiler(self.space, "2.4")



More information about the Pypy-commit mailing list