Author: mattip <[email protected]>
Branch: numpypy-longdouble
Changeset: r59134:14ed3b6a2d4f
Date: 2012-11-29 23:39 +0200
http://bitbucket.org/pypy/pypy/changeset/14ed3b6a2d4f/

Log:    test, implement dtype as container for long double

diff --git a/pypy/module/micronumpy/__init__.py 
b/pypy/module/micronumpy/__init__.py
--- a/pypy/module/micronumpy/__init__.py
+++ b/pypy/module/micronumpy/__init__.py
@@ -58,6 +58,8 @@
         'float16': 'interp_boxes.W_Float16Box',
         'float32': 'interp_boxes.W_Float32Box',
         'float64': 'interp_boxes.W_Float64Box',
+        'longdouble': 'interp_boxes.W_LongDoubleBox',
+        'longfloat': 'interp_boxes.W_LongDoubleBox',
         'intp': 'types.IntP.BoxType',
         'uintp': 'types.UIntP.BoxType',
         'flexible': 'interp_boxes.W_FlexibleBox',
diff --git a/pypy/module/micronumpy/interp_boxes.py 
b/pypy/module/micronumpy/interp_boxes.py
--- a/pypy/module/micronumpy/interp_boxes.py
+++ b/pypy/module/micronumpy/interp_boxes.py
@@ -8,12 +8,16 @@
 from pypy.objspace.std.inttype import int_typedef
 from pypy.objspace.std.complextype import complex_typedef
 from pypy.rlib.rarithmetic import LONG_BIT
+from pypy.rpython.lltypesystem import rffi
 from pypy.tool.sourcetools import func_with_new_name
 from pypy.module.micronumpy.arrayimpl.voidbox import VoidBoxStorage
 
 MIXIN_32 = (int_typedef,) if LONG_BIT == 32 else ()
 MIXIN_64 = (int_typedef,) if LONG_BIT == 64 else ()
 
+# Is this the proper place for this?
+long_double_size = rffi.sizeof_c_type('long double', ignore_errors=True)
+
 
 def new_dtype_getter(name):
     def _get_dtype(space):
@@ -226,6 +230,16 @@
 class W_Float64Box(W_FloatingBox, PrimitiveBox):
     descr__new__, _get_dtype = new_dtype_getter("float64")
 
+if long_double_size == 12:
+    class W_Float96Box(W_FloatingBox, PrimitiveBox):
+        descr__new__, _get_dtype = new_dtype_getter("float96")
+    W_LongDoubleBox = W_Float96Box
+elif long_double_size == 16:
+    class W_Float128Box(W_FloatingBox, PrimitiveBox):
+        descr__new__, _get_dtype = new_dtype_getter("float128")
+    W_LongDoubleBox = W_Float128Box
+else:
+    W_LongDoubleBox = W_Float64Box
 
 class W_FlexibleBox(W_GenericBox):
     def __init__(self, arr, ofs, dtype):
@@ -479,6 +493,18 @@
     __new__ = interp2app(W_Float64Box.descr__new__.im_func),
 )
 
+if long_double_size == 12:
+    W_Float96Box.typedef = TypeDef("float96", (W_FloatingBox.typedef),
+        __module__ = "numpypy",
+
+        __new__ = interp2app(W_Float96Box.descr__new__.im_func),
+    )
+elif long_double_size == 16:
+    W_Float128Box.typedef = TypeDef("float128", (W_FloatingBox.typedef),
+        __module__ = "numpypy",
+
+        __new__ = interp2app(W_Float128Box.descr__new__.im_func),
+    )
 
 W_FlexibleBox.typedef = TypeDef("flexible", W_GenericBox.typedef,
     __module__ = "numpypy",
diff --git a/pypy/module/micronumpy/interp_dtype.py 
b/pypy/module/micronumpy/interp_dtype.py
--- a/pypy/module/micronumpy/interp_dtype.py
+++ b/pypy/module/micronumpy/interp_dtype.py
@@ -412,13 +412,31 @@
             alternate_constructors=[space.w_float],
             aliases=["float"],
         )
-        # self.w_float128dtype = W_Dtype(
-        #     types.Float128(),
-        #     num=13,
-        #     kind=FLOATINGLTR,
-        #     name="float128",
-        #     ...
-        # )
+        if interp_boxes.long_double_size == 12:
+            self.w_float96dtype = W_Dtype(
+                types.Float96(),
+                num=13,
+                kind=FLOATINGLTR,
+                name="float96",
+                char="g",
+                w_box_type=space.gettypefor(interp_boxes.W_Float96Box),
+                aliases=["longfloat", "longdouble"],
+            )
+            longdouble = self.w_float96dtype
+        elif interp_boxes.long_double_size == 16:
+            self.w_float128dtype = W_Dtype(
+                types.Float128(),
+                num=13,
+                kind=FLOATINGLTR,
+                name="float128",
+                char="g",
+                w_box_type=space.gettypefor(interp_boxes.W_Floati128Box),
+                aliases=["longfloat", "longdouble"],
+            )
+            longdouble = self.w_float128dtype
+        else:
+            self.w_float64type.aliases += ["longfloat", "longdouble"]
+            longdouble = self.w_float64dtype
         self.w_complex64dtype = W_Dtype(
             types.Complex64(),
             num=14,
@@ -507,14 +525,16 @@
             self.w_int16dtype, self.w_uint16dtype, self.w_int32dtype,
             self.w_uint32dtype, self.w_longdtype, self.w_ulongdtype,
             self.w_int64dtype, self.w_uint64dtype,
-            self.w_float16dtype, self.w_float32dtype, self.w_float64dtype, 
self.w_complex64dtype,
-            self.w_complex128dtype,
+            self.w_float16dtype, self.w_float32dtype, self.w_float64dtype,
+            longdouble,
+            self.w_complex64dtype, self.w_complex128dtype,
             self.w_stringdtype, self.w_unicodedtype,
             self.w_voiddtype, self.w_intpdtype, self.w_uintpdtype,
         ]
         self.float_dtypes_by_num_bytes = sorted(
             (dtype.itemtype.get_element_size(), dtype)
-            for dtype in [self.w_float16dtype, self.w_float32dtype, 
self.w_float64dtype]
+            for dtype in [self.w_float16dtype, self.w_float32dtype,
+                          self.w_float64dtype, longdouble]
         )
         self.dtypes_by_name = {}
         # we reverse, so the stuff with lower numbers override stuff with
@@ -540,7 +560,7 @@
             'LONGLONG': self.w_int64dtype,
             'SHORT': self.w_int16dtype,
             'VOID': self.w_voiddtype,
-            #'LONGDOUBLE':,
+            'LONGDOUBLE': longdouble,
             'UBYTE': self.w_uint8dtype,
             'UINTP': self.w_ulongdtype,
             'ULONG': self.w_ulongdtype,
diff --git a/pypy/module/micronumpy/test/test_dtypes.py 
b/pypy/module/micronumpy/test/test_dtypes.py
--- a/pypy/module/micronumpy/test/test_dtypes.py
+++ b/pypy/module/micronumpy/test/test_dtypes.py
@@ -116,7 +116,8 @@
     def test_bool_binop_types(self):
         from _numpypy import array, dtype
         types = [
-            '?', 'b', 'B', 'h', 'H', 'i', 'I', 'l', 'L', 'q', 'Q', 'f', 'd', 
'e',
+            '?', 'b', 'B', 'h', 'H', 'i', 'I', 'l', 'L', 'q', 'Q', 'f', 'd', 
+            'e', 'g',
         ]
         a = array([True], '?')
         for t in types:
@@ -233,6 +234,7 @@
             (numpy.float16, 10.),
             (numpy.float32, 2.0),
             (numpy.float64, 4.32),
+            (numpy.longdouble, 4.32),
         ]:
             assert hash(tp(value)) == hash(value)
 
@@ -469,6 +471,18 @@
         assert numpy.float64('23.4') == numpy.float64(23.4)
         raises(ValueError, numpy.float64, '23.2df')
 
+    def test_longfloat(self):
+        import _numpypy as numpy
+        # it can be float96 or float128
+        assert numpy.longfloat.mro()[1:] == [numpy.floating,
+                                       numpy.inexact, numpy.number, 
+                                       numpy.generic, object]
+        a = numpy.array([1, 2, 3], numpy.longdouble)
+        assert repr(type(a[1])) == repr(numpy.longdouble)
+        assert numpy.float64(12) == numpy.longdouble(12)
+        assert numpy.float64(12) == numpy.longfloat(12)
+        raises(ValueError, numpy.longfloat, '23.2df')
+
     def test_complex_floating(self):
         import _numpypy as numpy
 
diff --git a/pypy/module/micronumpy/types.py b/pypy/module/micronumpy/types.py
--- a/pypy/module/micronumpy/types.py
+++ b/pypy/module/micronumpy/types.py
@@ -981,6 +981,35 @@
     BoxType = interp_boxes.W_Float64Box
     format_code = "d"
 
+if interp_boxes.long_double_size == 12:
+    class Float96(BaseType, Float):
+        _attrs_ = ()
+
+        T = rffi.LONGDOUBLE
+        BoxType = interp_boxes.W_Float96Box
+        format_code = "q"
+
+    class NonNativeFloat96(BaseType, NonNativeFloat):
+        _attrs_ = ()
+
+        T = rffi.LONGDOUBLE
+        BoxType = interp_boxes.W_Float96Box
+        format_code = "q"
+elif interp_boxes.long_double_size == 16:
+    class Float128(BaseType, Float):
+        _attrs_ = ()
+
+        T = rffi.LONGDOUBLE
+        BoxType = interp_boxes.W_Float128Box
+        format_code = "q"
+
+    class NonNativeFloat128(BaseType, NonNativeFloat):
+        _attrs_ = ()
+
+        T = rffi.LONGDOUBLE
+        BoxType = interp_boxes.W_Float128Box
+        format_code = "q"
+
 class ComplexFloating(object):
     _mixin_ = True
     _attrs_ = ()
diff --git a/pypy/rlib/rstruct/test/test_ieee.py 
b/pypy/rlib/rstruct/test/test_ieee.py
--- a/pypy/rlib/rstruct/test/test_ieee.py
+++ b/pypy/rlib/rstruct/test/test_ieee.py
@@ -34,10 +34,20 @@
             float_pack4 = "overflow"
         assert struct_pack4 == float_pack4
 
+        if float_pack4 == "overflow":
+            return
+
         # if we didn't overflow, try round-tripping the binary32 value
-        if float_pack4 != "overflow":
-            roundtrip = float_pack(float_unpack(float_pack4, 4), 4)
-            assert float_pack4 == roundtrip
+        roundtrip = float_pack(float_unpack(float_pack4, 4), 4)
+        assert float_pack4 == roundtrip
+
+        try:
+            float_pack2 = float_pack(x, 2)
+        except OverflowError:
+            return
+
+        roundtrip = float_pack(float_unpack(float_pack2, 2), 2)
+        assert (float_pack2,x) == (roundtrip,x)
 
     def test_infinities(self):
         self.check_float(float('inf'))
@@ -54,6 +64,9 @@
         L = float_pack(float('nan'), 4)
         z = float_unpack(L, 4)
         assert repr(z) == 'nan'
+        L = float_pack(float('nan'), 2)
+        z = float_unpack(L, 2)
+        assert repr(z) == 'nan'
 
     def test_simple(self):
         test_values = [1e-10, 0.00123, 0.5, 0.7, 1.0, 123.456, 1e10]
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to