[pypy-commit] pypy default: Add support for half floats in the RPython rstruct module.
amauryfa
pypy.commits at gmail.com
Wed Dec 13 17:29:29 EST 2017
Author: Amaury Forgeot d'Arc <amauryfa at gmail.com>
Branch:
Changeset: r93412:ca5586010ac3
Date: 2017-12-11 20:29 +0100
http://bitbucket.org/pypy/pypy/changeset/ca5586010ac3/
Log: Add support for half floats in the RPython rstruct module.
diff --git a/rpython/rlib/rstruct/standardfmttable.py b/rpython/rlib/rstruct/standardfmttable.py
--- a/rpython/rlib/rstruct/standardfmttable.py
+++ b/rpython/rlib/rstruct/standardfmttable.py
@@ -105,6 +105,18 @@
_pack_string(fmtiter, string, count-1)
+def pack_halffloat(fmtiter):
+ size = 2
+ fl = fmtiter.accept_float_arg()
+ try:
+ result = ieee.pack_float(fmtiter.wbuf, fmtiter.pos,
+ fl, size, fmtiter.bigendian)
+ except OverflowError:
+ raise StructOverflowError("float too large for format 'e'")
+ else:
+ fmtiter.advance(size)
+ return result
+
def make_float_packer(TYPE):
size = rffi.sizeof(TYPE)
def packer(fmtiter):
@@ -247,6 +259,11 @@
end = count
fmtiter.appendobj(data[1:end])
+ at specialize.argtype(0)
+def unpack_halffloat(fmtiter):
+ data = fmtiter.read(2)
+ fmtiter.appendobj(ieee.unpack_float(data, fmtiter.bigendian))
+
def make_ieee_unpacker(TYPE):
@specialize.argtype(0)
def unpack_ieee(fmtiter):
@@ -374,6 +391,8 @@
'needcount' : True },
'p':{ 'size' : 1, 'pack' : pack_pascal, 'unpack' : unpack_pascal,
'needcount' : True },
+ 'e':{ 'size' : 2, 'pack' : pack_halffloat,
+ 'unpack' : unpack_halffloat},
'f':{ 'size' : 4, 'pack' : make_float_packer(rffi.FLOAT),
'unpack' : unpack_float},
'd':{ 'size' : 8, 'pack' : make_float_packer(rffi.DOUBLE),
diff --git a/rpython/rlib/rstruct/test/test_pack.py b/rpython/rlib/rstruct/test/test_pack.py
--- a/rpython/rlib/rstruct/test/test_pack.py
+++ b/rpython/rlib/rstruct/test/test_pack.py
@@ -138,6 +138,19 @@
self.check('f', 123.456)
self.check('d', 123.456789)
+ def test_pack_halffloat(self):
+ if self.fmttable is nativefmttable.native_fmttable:
+ # Host Python cannot handle half floats.
+ return
+ size = 2
+ wbuf = MutableStringBuffer(size)
+ self.mypack_into('e', wbuf, 6.5e+04)
+ got = wbuf.finish()
+ if self.bigendian:
+ assert got == b'\x7b\xef'
+ else:
+ assert got == b'\xef\x7b'
+
def test_float_overflow(self):
if self.fmt_prefix == '@':
# native packing, no overflow
diff --git a/rpython/rlib/rstruct/test/test_runpack.py b/rpython/rlib/rstruct/test/test_runpack.py
--- a/rpython/rlib/rstruct/test/test_runpack.py
+++ b/rpython/rlib/rstruct/test/test_runpack.py
@@ -78,6 +78,10 @@
assert f != 12.34 # precision lost
assert abs(f - 12.34) < 1E-6
+ def test_unpack_halffloat(self):
+ assert runpack(">e", b"\x7b\xef") == 64992.0
+ assert runpack("<e", b"\xef\x7b") == 64992.0
+
def test_unpack_standard_little(self):
def unpack(fmt, data):
def fn():
More information about the pypy-commit
mailing list