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