[pypy-commit] pypy can_cast: Implement min_dtype() on float types

rlamy noreply at buildbot.pypy.org
Thu Apr 30 18:50:03 CEST 2015


Author: Ronan Lamy <ronan.lamy at gmail.com>
Branch: can_cast
Changeset: r76953:244204b77d90
Date: 2015-04-30 17:38 +0100
http://bitbucket.org/pypy/pypy/changeset/244204b77d90/

Log:	Implement min_dtype() on float types

diff --git a/pypy/module/micronumpy/test/test_ndarray.py b/pypy/module/micronumpy/test/test_ndarray.py
--- a/pypy/module/micronumpy/test/test_ndarray.py
+++ b/pypy/module/micronumpy/test/test_ndarray.py
@@ -4053,3 +4053,8 @@
         assert np.can_cast(127, np.int8)
         assert not np.can_cast(128, np.int8)
         assert np.can_cast(128, np.int16)
+
+        assert np.can_cast(np.float32('inf'), np.float32)
+        assert np.can_cast(float('inf'), np.float32)  # XXX: False in CNumPy?!
+        assert np.can_cast(3.3e38, np.float32)
+        assert not np.can_cast(3.4e38, np.float32)
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
@@ -1026,6 +1026,7 @@
     kind = NPY.FLOATINGLTR
     char = NPY.HALFLTR
     BoxType = boxes.W_Float16Box
+    max_value = 65000.
 
     @specialize.argtype(1)
     def box(self, value):
@@ -1070,6 +1071,7 @@
     char = NPY.FLOATLTR
     BoxType = boxes.W_Float32Box
     format_code = "f"
+    max_value = 3.4e38
 
 class Float64(BaseType, Float):
     T = rffi.DOUBLE
@@ -1078,6 +1080,7 @@
     char = NPY.DOUBLELTR
     BoxType = boxes.W_Float64Box
     format_code = "d"
+    max_value = 1.7e308
 
 class ComplexFloating(object):
     _mixin_ = True
@@ -2487,8 +2490,7 @@
 
 signed_types = [Int8, Int16, Int32, Int64, Long]
 
-for Int_t in signed_types:
-    UInt_t = Int_t.Unsigned
+def make_integer_min_dtype(Int_t, UInt_t):
     smaller_types = [tp for tp in signed_types
             if rffi.sizeof(tp.T) < rffi.sizeof(Int_t.T)]
     smaller_types = unrolling_iterable(
@@ -2528,3 +2530,32 @@
                         return Small.num, Small.num
             return Int_t.num, Int_t.num
     Int_t.BoxType.min_dtype = min_dtype
+
+for Int_t in signed_types:
+    UInt_t = Int_t.Unsigned
+    make_integer_min_dtype(Int_t, UInt_t)
+
+
+smaller_float_types = {
+        Float16: [], Float32: [Float16], Float64: [Float16, Float32],
+        FloatLong: [Float16, Float32, Float64]}
+
+def make_float_min_dtype(Float_t):
+    smaller_types = unrolling_iterable(smaller_float_types[Float_t])
+    smallest_type = Float16
+    def min_dtype(self):
+        value = float(self.value)
+        if not rfloat.isfinite(value):
+            tp = smallest_type
+        else:
+            for SmallFloat in smaller_types:
+                if -SmallFloat.max_value < value < SmallFloat.max_value:
+                    tp = SmallFloat
+                    break
+            else:
+                tp = Float_t
+        return tp.num, tp.num
+    Float_t.BoxType.min_dtype = min_dtype
+
+for Float_t in float_types:
+    make_float_min_dtype(Float_t)


More information about the pypy-commit mailing list