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