[pypy-svn] pypy default: Fix the logic to have explicit overflow detection; we cannot rely

arigo commits-noreply at bitbucket.org
Thu Jan 27 18:47:53 CET 2011


Author: Armin Rigo <arigo at tunes.org>
Branch: 
Changeset: r41401:700ac75829b9
Date: 2011-01-27 18:47 +0100
http://bitbucket.org/pypy/pypy/changeset/700ac75829b9/

Log:	Fix the logic to have explicit overflow detection; we cannot rely on
	int() at RPython-level.

diff --git a/pypy/objspace/std/test/test_floatobject.py b/pypy/objspace/std/test/test_floatobject.py
--- a/pypy/objspace/std/test/test_floatobject.py
+++ b/pypy/objspace/std/test/test_floatobject.py
@@ -558,6 +558,9 @@
         self.identical(fromHex('0X0p-1076'), 0.0)
         self.identical(fromHex('-0X0p-2000'), -0.0)
         self.identical(fromHex('-0x0p-123456789123456789'), -0.0)
+        self.identical(fromHex('0x1.0p00000000000000000000000000000003'), 8.0)
+        self.identical(fromHex('0x1.0p+0000000000000000000000000000003'), 8.0)
+        self.identical(fromHex('0x1.0p-000000000000000000000000000003'), 0.125)
 
         # values that should underflow to 0
         self.identical(fromHex('0X1p-1075'), 0.0)

diff --git a/pypy/objspace/std/floattype.py b/pypy/objspace/std/floattype.py
--- a/pypy/objspace/std/floattype.py
+++ b/pypy/objspace/std/floattype.py
@@ -170,8 +170,10 @@
                 raise OperationError(space.w_ValueError,
                                      space.wrap("invalid hex string"))
             i += 1
-            exp_start = i
+            exp_sign = 1
             if s[i] == "-" or s[i] == "+":
+                if s[i] == "-":
+                    exp_sign = -1
                 i += 1
                 if i == length:
                     raise OperationError(space.w_ValueError,
@@ -179,18 +181,30 @@
             if not s[i].isdigit():
                 raise OperationError(space.w_ValueError,
                                      space.wrap("invalid hex string"))
+            exp = ord(s[i]) - ord('0')
             i += 1
             while i < length and s[i].isdigit():
+                exp = exp * 10 + (ord(s[i]) - ord('0'))
+                if exp >= (sys.maxint-9) // 10:
+                    if exp_sign > 0:
+                        exp_sign = 2    # overflow in positive numbers
+                    else:
+                        exp_sign = -2   # overflow in negative numbers
                 i += 1
-            exp = int(s[exp_start:i])
+            if exp_sign == -1:
+                exp = -exp
+            elif exp_sign == -2:
+                exp = -sys.maxint / 2
+            elif exp_sign == 2:
+                exp = sys.maxint / 2
         else:
             exp = 0
         while (total_digits and
                _hex_digit(s, total_digits - 1, co_end, float_digits) == 0):
             total_digits -= 1
-        if not total_digits or exp < -sys.maxint / 2:
+        if not total_digits or exp <= -sys.maxint / 2:
             value = 0.0
-        elif exp > sys.maxint // 2:
+        elif exp >= sys.maxint // 2:
             raise OperationError(space.w_OverflowError, space.wrap("too large"))
         else:
             exp -=  4 * float_digits


More information about the Pypy-commit mailing list