Author: mattip <[email protected]>
Branch: numpypy.float16
Changeset: r58741:92781d000de0
Date: 2012-11-05 20:57 +0200
http://bitbucket.org/pypy/pypy/changeset/92781d000de0/

Log:    add and test size=2 to ieee float_pack, float_unpack

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
@@ -930,7 +930,7 @@
     BoxType = interp_boxes.W_Float16Box
 
     def pack_str(self, box):
-        fbits = float_pack(self.unbox(box))
+        fbits = float_pack(self.unbox(box), 4)
         hbits = halffloat.floatbits_to_halfbits(fbits)
         return struct.pack('H', hbits)
 
diff --git a/pypy/rlib/rstruct/ieee.py b/pypy/rlib/rstruct/ieee.py
--- a/pypy/rlib/rstruct/ieee.py
+++ b/pypy/rlib/rstruct/ieee.py
@@ -15,7 +15,7 @@
       - 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; except wrong results
+    We assume that x is finite and nonnegative; expect wrong results
     if you use this for negative x.
 
     """
@@ -27,7 +27,7 @@
 
 
 def float_unpack(Q, size):
-    """Convert a 32-bit or 64-bit integer created
+    """Convert a 16-bit, 32-bit or 64-bit integer created
     by float_pack into a Python float."""
 
     if size == 8:
@@ -40,6 +40,11 @@
         MAX_EXP = 128    # FLT_MAX_EXP
         MANT_DIG = 24    # FLT_MANT_DIG
         BITS = 32
+    elif size == 2:
+        MIN_EXP = -13   
+        MAX_EXP = 16    
+        MANT_DIG = 11
+        BITS = 16
     else:
         raise ValueError("invalid size value")
 
@@ -83,6 +88,11 @@
         MAX_EXP = 128    # FLT_MAX_EXP
         MANT_DIG = 24    # FLT_MANT_DIG
         BITS = 32
+    elif size == 2:
+        MIN_EXP = -13   
+        MAX_EXP = 16    
+        MANT_DIG = 11
+        BITS = 16
     else:
         raise ValueError("invalid size value")
 
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
@@ -110,3 +110,33 @@
             if isnan(x):
                 continue
             self.check_float(x)
+
+    def test_halffloat_exact(self):
+        cases = [[0, 0], [10, 18688], [-10, 51456], [10e3, 28898], 
+                 [float('inf'), 31744], [-float('inf'), 64512]]
+        for c,h in cases:
+            hbit = float_pack(c, 2)
+            assert hbit == h
+            assert c == float_unpack(h, 2)
+
+    def test_halffloat_inexact(self):
+        cases = [[10.001, 18688, 10.], [-10.001, 51456, -10],
+                 [0.027588, 10000, 0.027587890625],
+                 [22001, 30047, 22000]]
+        for c,h,f in cases:
+            hbit = float_pack(c, 2)
+            assert hbit == h
+            assert f == float_unpack(h, 2)
+
+    def test_halffloat_overunderflow(self):
+        import math
+        cases = [[670000, float('inf')], [-67000, -float('inf')],
+                 [1e-08, 0], [-1e-8, -0.]]
+        for f1, f2 in cases:
+            try:
+                f_out = float_unpack(float_pack(f1, 2), 2)
+            except OverflowError:
+                f_out = math.copysign(float('inf'), f1)
+            assert f_out == f2
+            assert math.copysign(1., f_out) == math.copysign(1., f2)
+
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to