[pypy-svn] r75722 - in pypy/branch/fast-forward/pypy: module/math objspace/std rlib/rstruct rpython/lltypesystem/module

benjamin at codespeak.net benjamin at codespeak.net
Thu Jul 1 18:28:57 CEST 2010


Author: benjamin
Date: Thu Jul  1 18:28:56 2010
New Revision: 75722

Modified:
   pypy/branch/fast-forward/pypy/module/math/interp_math.py
   pypy/branch/fast-forward/pypy/objspace/std/marshal_impl.py
   pypy/branch/fast-forward/pypy/rlib/rstruct/ieee.py
   pypy/branch/fast-forward/pypy/rpython/lltypesystem/module/ll_math.py
Log:
revert unintended math changes

Modified: pypy/branch/fast-forward/pypy/module/math/interp_math.py
==============================================================================
--- pypy/branch/fast-forward/pypy/module/math/interp_math.py	(original)
+++ pypy/branch/fast-forward/pypy/module/math/interp_math.py	Thu Jul  1 18:28:56 2010
@@ -46,13 +46,6 @@
     return space.wrap(r)
 math2._annspecialcase_ = 'specialize:arg(1)'
 
-def copysign(space, x, y):
-    """copysign(x, y)
-
-    Return x with the sign of y."""
-    return math2(space, math.copysign, x, y)
-copysign.unwrap_spec = [ObjSpace, float, float]
-
 def pow(space, x, y):
     """pow(x,y)
        

Modified: pypy/branch/fast-forward/pypy/objspace/std/marshal_impl.py
==============================================================================
--- pypy/branch/fast-forward/pypy/objspace/std/marshal_impl.py	(original)
+++ pypy/branch/fast-forward/pypy/objspace/std/marshal_impl.py	Thu Jul  1 18:28:56 2010
@@ -169,11 +169,11 @@
 
 def pack_float(f):
     result = []
-    ieee.pack_float(result, f, 8, False)
+    ieee.pack_float8(result, f)
     return ''.join(result)
 
 def unpack_float(s):
-    return ieee.unpack_float(s, False)
+    return ieee.unpack_float8(s)
 
 def marshal_w__Float(space, w_float, m):
     if m.version > 1:

Modified: pypy/branch/fast-forward/pypy/rlib/rstruct/ieee.py
==============================================================================
--- pypy/branch/fast-forward/pypy/rlib/rstruct/ieee.py	(original)
+++ pypy/branch/fast-forward/pypy/rlib/rstruct/ieee.py	Thu Jul  1 18:28:56 2010
@@ -3,7 +3,124 @@
 """
 
 import math
-from pypy.rlib.rarithmetic import r_longlong, isinf, isnan, INFINITY, NAN
+from pypy.rlib.rarithmetic import r_longlong, r_ulonglong, isinf, isnan, INFINITY, NAN
+
+
+def py3round(x):
+    """Python 3 round function semantics, in Python 2 code.
+
+    We want to round x to the nearest int, but:
+      - return an int, not a float
+      - do round-half-to-even, not round-half-away-from-zero.
+
+    We assume that x is finite and nonnegative.
+
+    """
+    int_part = r_ulonglong(x)
+    frac_part = x - int_part
+    if frac_part > 0.5 or frac_part == 0.5 and (int_part & 1):
+        int_part += 1
+    return int_part
+
+
+def float_pack(x, size):
+    """Convert a Python float x into a 64-bit unsigned integer
+    with the same byte representation."""
+
+    if size == 8:
+        MIN_EXP = -1021  # = sys.float_info.min_exp
+        MAX_EXP = 1024   # = sys.float_info.max_exp
+        MANT_DIG = 53    # = sys.float_info.mant_dig
+    elif size == 4:
+        MIN_EXP = -125   # C's FLT_MIN_EXP
+        MAX_EXP = 128    # FLT_MAX_EXP
+        MANT_DIG = 24    # FLT_MANT_DIG
+    else:
+        raise ValueError("invalid size value")
+
+    sign = math.copysign(1.0, x) < 0.0
+    if isinf(x):
+        mant = 0
+        exp = MAX_EXP - MIN_EXP + 2
+    elif isnan(x):
+        mant = 1 << (MANT_DIG-2)
+        exp = MAX_EXP - MIN_EXP + 2
+    elif x == 0.0:
+        mant = 0
+        exp = 0
+    else:
+        m, e = math.frexp(abs(x))
+        if e < MIN_EXP:
+            # Subnormal result (or possibly smallest normal, after rounding).
+            if e < MIN_EXP - MANT_DIG:
+                # Underflow to zero; not possible when size == 8.
+                mant = r_ulonglong(0)
+            else:
+                # For size == 8, can substitute 'int' for 'py3round', both
+                # here and below: the argument will always be integral.
+                mant = py3round(m * (1 << e - (MIN_EXP - MANT_DIG)))
+            exp = 0
+        elif e > MAX_EXP:
+            # Overflow to infinity: not possible when size == 8.
+            raise OverflowError("float too large to pack with f format")
+        else:
+            mant = py3round(m * (1 << MANT_DIG))
+            exp = e - MIN_EXP
+    # N.B. It's important that the + mant really is an addition, not just a
+    # bitwise 'or'.  In extreme cases, mant may have MANT_DIG+1 significant
+    # bits, as a result of rounding.
+    return ((sign << 8*size - 1) | (exp << MANT_DIG - 1)) + mant
+
+
+def float_unpack(Q, size):
+    """Convert a 32-bit or 64-bit integer created
+    by float_pack into a Python float."""
+
+    if size == 8:
+        MIN_EXP = -1021  # = sys.float_info.min_exp
+        MAX_EXP = 1024   # = sys.float_info.max_exp
+        MANT_DIG = 53    # = sys.float_info.mant_dig
+    elif size == 4:
+        MIN_EXP = -125   # C's FLT_MIN_EXP
+        MAX_EXP = 128    # FLT_MAX_EXP
+        MANT_DIG = 24    # FLT_MANT_DIG
+    else:
+        raise ValueError("invalid size value")
+
+    # extract pieces
+    sign = Q >> 8*size - 1
+    Q -= sign << 8*size - 1
+    exp = Q >> MANT_DIG - 1
+    Q -= exp << MANT_DIG - 1
+    mant = Q
+
+    if exp == MAX_EXP - MIN_EXP + 2:
+        # nan or infinity
+        result = float('nan') if mant else float('inf')
+    elif exp == 0:
+        # subnormal or zero
+        result = math.ldexp(float(mant), MIN_EXP - MANT_DIG)
+    else:
+        # normal
+        exp -= 1
+        mant += 1 << MANT_DIG - 1
+        result = math.ldexp(float(mant), exp + MIN_EXP - MANT_DIG)
+    return -result if sign else result
+
+
+def pack_float8(result, x):
+    unsigned = float_pack(x, 8)
+    for i in range(8):
+        result.append(chr((unsigned >> (i * 8)) & 0xFF))
+
+
+def unpack_float8(s):
+    unsigned = r_ulonglong(0)
+    for i in range(8):
+        unsigned |= ord(s[7 - i]) << (i * 8)
+    print unsigned
+    return float_unpack(unsigned, 8)
+
 
 def pack_float(result, number, size, bigendian):
     """Append to 'result' the 'size' characters of the 32-bit or 64-bit

Modified: pypy/branch/fast-forward/pypy/rpython/lltypesystem/module/ll_math.py
==============================================================================
--- pypy/branch/fast-forward/pypy/rpython/lltypesystem/module/ll_math.py	(original)
+++ pypy/branch/fast-forward/pypy/rpython/lltypesystem/module/ll_math.py	Thu Jul  1 18:28:56 2010
@@ -36,6 +36,8 @@
 math_fmod  = llexternal('fmod',  [rffi.DOUBLE, rffi.DOUBLE], rffi.DOUBLE)
 math_hypot = llexternal(underscore + 'hypot',
                         [rffi.DOUBLE, rffi.DOUBLE], rffi.DOUBLE)
+math_isnan = llexternal('isnan', [rffi.DOUBLE], rffi.INT)
+math_isinf = llexternal('isinf', [rffi.DOUBLE], rffi.INT)
 
 # ____________________________________________________________
 #



More information about the Pypy-commit mailing list