[pypy-svn] r14277 - in pypy/dist/pypy/objspace/std: . test

tismer at codespeak.net tismer at codespeak.net
Tue Jul 5 14:08:34 CEST 2005


Author: tismer
Date: Tue Jul  5 14:08:33 2005
New Revision: 14277

Modified:
   pypy/dist/pypy/objspace/std/longobject.py
   pypy/dist/pypy/objspace/std/test/test_longobject.py
Log:
_FromDouble works, too

Modified: pypy/dist/pypy/objspace/std/longobject.py
==============================================================================
--- pypy/dist/pypy/objspace/std/longobject.py	(original)
+++ pypy/dist/pypy/objspace/std/longobject.py	Tue Jul  5 14:08:33 2005
@@ -885,9 +885,9 @@
     assert x > 0.0
     return x * sign, exponent
 
-##def isinf(x):
-##    return x != 0.0 and x / 2 == x
-##
+def isinf(x):
+    return x != 0.0 and x / 2 == x
+
 ##def ldexp(x, exp):
 ##    assert type(x) is float
 ##    lb1 = LONG_BIT - 1
@@ -935,3 +935,29 @@
     except OverflowError:
         raise OperationError(space.w_OverflowError,
                              space.wrap("long/long too large for a float"))
+
+
+def _FromDouble(space, dval):
+    """ Create a new long int object from a C double """
+    neg = 0
+    if isinf(dval):
+        raise OperationError(space.w_OverflowError,
+                             space.wrap("cannot convert float infinity to long"))
+    if dval < 0.0:
+        neg = 1
+        dval = -dval
+    frac, expo = math.frexp(dval) # dval = frac*2**expo; 0.0 <= frac < 1.0
+    if expo <= 0:
+        return W_LongObject(space, [r_uint(0)], 0)
+    ndig = (expo-1) // SHORT_BIT + 1 # Number of 'digits' in result
+    digitpairs = (ndig + 1) // 2
+    v = W_LongObject(space, [r_uint(0)] * digitpairs, 1)
+    frac = math.ldexp(frac, (expo-1) % SHORT_BIT + 1)
+    for i in range(ndig-1, -1, -1):
+        bits = int(frac)
+        v._setshort(i, r_uint(bits))
+        frac -= float(bits)
+        frac = math.ldexp(frac, SHORT_BIT)
+    if neg:
+        v.sign = -1
+    return v

Modified: pypy/dist/pypy/objspace/std/test/test_longobject.py
==============================================================================
--- pypy/dist/pypy/objspace/std/test/test_longobject.py	(original)
+++ pypy/dist/pypy/objspace/std/test/test_longobject.py	Tue Jul  5 14:08:33 2005
@@ -4,6 +4,7 @@
 from pypy.objspace.std import longobject as lobj
 from pypy.objspace.std.objspace import FailedToImplement
 from pypy.rpython.rarithmetic import r_uint
+from pypy.interpreter.error import OperationError
 
 objspacename = 'std'
 
@@ -112,6 +113,18 @@
         f1 = lobj.W_LongObject(self.space, *lobj.args_from_long(x))
         assert raises(OverflowError, lobj._AsDouble, f1)
 
+    def test__FromDouble(self):
+        x = 1234567890.1234567890
+        f1 = lobj._FromDouble(self.space, x)
+        y = lobj._AsDouble(f1)
+        assert f1.longval() == long(x)
+        # check overflow
+        x = 12345.6789e10000000000000000000000000000
+        try:
+            lobj._FromDouble(self.space, x)
+        except OperationError, e:
+            assert e.w_type is self.space.w_OverflowError
+
     def test_eq(self):
         x = 5858393919192332223L
         y = 585839391919233111223311112332L



More information about the Pypy-commit mailing list