[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH] pickles/ieee754.pk: add half->single and single->double conversi
From: |
Mohammad-Reza Nabipoor |
Subject: |
[PATCH] pickles/ieee754.pk: add half->single and single->double conversion funcs |
Date: |
Sun, 29 Dec 2024 20:28:26 +0100 |
2024-12-19 Mohammad-Reza Nabipoor <mnabipoor@gnu.org>
* pickles/ieee754.pk (ieee754_16to32): New function to convert
`IEEE754_binary16' to `IEEE754_binary32'.
(ieee754_32to64): New function to convert `IEEE754_binary32'
to `IEEE754_binary64'.
* testsuite/poke.pickles/ieee754-test.pk: Add new tests for
conversion of binary16 to binary 32, and binary32 to binary64.
---
Hi Jose!
If you accept the `[PATCH] pickles: extend and fix ieee754.pk' patch,
then this one is the next step in adding conversion of narrower floats
to wider ones.
Regards,
Mohammad-Reza
ChangeLog | 9 ++++
pickles/ieee754.pk | 71 ++++++++++++++++++++++++++
testsuite/poke.pickles/ieee754-test.pk | 62 +++++++++++++++++++++-
3 files changed, 141 insertions(+), 1 deletion(-)
diff --git a/ChangeLog b/ChangeLog
index 74f4fb40..8534f5b5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2024-12-19 Mohammad-Reza Nabipoor <mnabipoor@gnu.org>
+
+ * pickles/ieee754.pk (ieee754_16to32): New function to convert
+ `IEEE754_binary16' to `IEEE754_binary32'.
+ (ieee754_32to64): New function to convert `IEEE754_binary32'
+ to `IEEE754_binary64'.
+ * testsuite/poke.pickles/ieee754-test.pk: Add new tests for
+ conversion of binary16 to binary 32, and binary32 to binary64.
+
2024-12-16 Mohammad-Reza Nabipoor <mnabipoor@gnu.org>
* pickles/ieee754.pk (IEEE754_binary64.is_qnan_p): Use explicit
diff --git a/pickles/ieee754.pk b/pickles/ieee754.pk
index 7dba6ca0..19638d1e 100644
--- a/pickles/ieee754.pk
+++ b/pickles/ieee754.pk
@@ -16,6 +16,9 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+// Reference for conversions:
+// http://www.fox-toolkit.org/ftp/fasthalffloatconversion.pdf
+
type IEEE754_binary16 =
struct int<16>
{
@@ -70,3 +73,71 @@ type IEEE754_binary64 =
type Float16 = IEEE754_binary16;
type Float32 = IEEE754_binary32;
type Float64 = IEEE754_binary64;
+
+fun ieee754_16to32 = (IEEE754_binary16 f16) IEEE754_binary32:
+{
+ if (f16.is_zero_p)
+ return IEEE754_binary32 {sign=f16.sign};
+ if (f16.is_inf_p)
+ return IEEE754_binary32 {sign=f16.sign, exp=-1};
+ if (f16.is_nan_p)
+ return IEEE754_binary32 {
+ sign=f16.sign, exp=-1, frac=f16.frac:::(0 as uint<13>),
+ };
+ if (f16.is_subnormal_p)
+ {
+ var f32 = IEEE754_binary32 {sign=f16.sign, exp=0-15+127},
+ frac = f16.frac as int<11>;
+
+ // Normalize
+ while (1)
+ {
+ frac = frac <<. 1;
+ if (frac < 0)
+ break;
+ --f32.exp;
+ }
+ f32.frac = (frac as uint<10>):::(0 as uint<13>);
+
+ return f32;
+ }
+ return IEEE754_binary32 {
+ sign=f16.sign,
+ exp=f16.exp - 15 + 127, // Change the bias from 15 to 127.
+ frac=f16.frac:::(0 as uint<13>),
+ };
+}
+
+fun ieee754_32to64 = (IEEE754_binary32 f32) IEEE754_binary64:
+{
+ if (f32.is_zero_p)
+ return IEEE754_binary64 {sign=f32.sign};
+ if (f32.is_inf_p)
+ return IEEE754_binary64 {sign=f32.sign, exp=-1};
+ if (f32.is_nan_p)
+ return IEEE754_binary64 {
+ sign=f32.sign, exp=-1, frac=f32.frac:::(0 as uint<29>),
+ };
+ if (f32.is_subnormal_p)
+ {
+ var f64 = IEEE754_binary64 {sign=f32.sign, exp=0-127+1023},
+ frac = f32.frac as int<24>;
+
+ // Normalize
+ while (1)
+ {
+ frac = frac <<. 1;
+ if (frac < 0)
+ break;
+ --f64.exp;
+ }
+ f64.frac = (frac as uint<23>):::(0 as uint<29>);
+
+ return f64;
+ }
+ return IEEE754_binary64 {
+ sign=f32.sign,
+ exp=f32.exp - 127 + 1023, // Change the bias from 127 to 1023.
+ frac=f32.frac:::(0 as uint<29>),
+ };
+}
diff --git a/testsuite/poke.pickles/ieee754-test.pk
b/testsuite/poke.pickles/ieee754-test.pk
index 7fc93167..541c4281 100644
--- a/testsuite/poke.pickles/ieee754-test.pk
+++ b/testsuite/poke.pickles/ieee754-test.pk
@@ -158,7 +158,7 @@ var tests = [
assert (subnormal2.is_subnormal_p);
},
},
- PkTest {
+ PkTest {
name = "binary64",
func = lambda (string name) void:
{
@@ -203,6 +203,66 @@ var tests = [
assert (subnormal2.is_subnormal_p);
},
},
+ PkTest {
+ name = "binary16->binary32",
+ func = lambda (string name) void:
+ {
+ assert (ieee754_16to32 (0x0000U as IEEE754_binary16)
+ == (0x00000000U as IEEE754_binary32) /*0.000000e+00*/);
+ assert (ieee754_16to32 (0x0001U as IEEE754_binary16)
+ == (0x33800000U as IEEE754_binary32) /*5.960464e-08*/);
+ assert (ieee754_16to32 (0x0003U as IEEE754_binary16)
+ == (0x34400000U as IEEE754_binary32) /*1.788139e-07*/);
+ assert (ieee754_16to32 (0x0100U as IEEE754_binary16)
+ == (0x37800000U as IEEE754_binary32) /*1.525879e-05*/);
+ assert (ieee754_16to32 (0x03feU as IEEE754_binary16)
+ == (0x387f8000U as IEEE754_binary32) /*6.091595e-05*/);
+ assert (ieee754_16to32 (0x03ffU as IEEE754_binary16)
+ == (0x387fc000U as IEEE754_binary32) /*6.097555e-05*/);
+
+ assert (ieee754_16to32 (0x3c00U as IEEE754_binary16)
+ == (0x3f800000U as IEEE754_binary32) /*1.000000e+00*/);
+ assert (ieee754_16to32 (0x4248U as IEEE754_binary16)
+ == (0x40490000U as IEEE754_binary32) /*3.140625e+00*/);
+ assert (ieee754_16to32 (0x3da8U as IEEE754_binary16)
+ == (0x3fb50000U as IEEE754_binary32) /*1.414062e+00*/);
+ assert (ieee754_16to32 (0xfe00U as IEEE754_binary16)
+ == (0xffc00000U as IEEE754_binary32) /*-nan*/);
+ assert (ieee754_16to32 (0x7e00U as IEEE754_binary16)
+ == (0x7fc00000U as IEEE754_binary32) /*nan*/);
+ assert (ieee754_16to32 (0x7c00U as IEEE754_binary16)
+ == (0x7f800000U as IEEE754_binary32) /*inf*/);
+ },
+ },
+ PkTest {
+ name = "binary32->binary64",
+ func = lambda (string name) void:
+ {
+ assert (ieee754_32to64 (0x00000000U as IEEE754_binary32)
/*0.000000e+00*/
+ == (0x0000000000000000U as IEEE754_binary64) /*0.000000e+00*/);
+ assert (ieee754_32to64 (0x00000001U as IEEE754_binary32)
/*1.401298e-45*/
+ == (0x36a0000000000000U as IEEE754_binary64) /*1.401298e-45*/);
+ assert (ieee754_32to64 (0x00400000U as IEEE754_binary32)
/*5.877472e-39*/
+ == (0x3800000000000000U as IEEE754_binary64) /*5.877472e-39*/);
+ assert (ieee754_32to64 (0x007fffffU as IEEE754_binary32)
/*1.175494e-38*/
+ == (0x380fffffc0000000U as IEEE754_binary64) /*1.175494e-38*/);
+ assert (ieee754_32to64 (0x00800000U as IEEE754_binary32)
/*1.175494e-38*/
+ == (0x3810000000000000U as IEEE754_binary64) /*1.175494e-38*/);
+
+ assert (ieee754_32to64 (0x3f800000U as IEEE754_binary32)
/*1.000000e+00*/
+ == (0x3ff0000000000000U as IEEE754_binary64) /*1.000000e+00*/);
+ assert (ieee754_32to64 (0x40490e56U as IEEE754_binary32)
/*3.141500e+00*/
+ == (0x400921cac0000000U as IEEE754_binary64) /*3.141500e+00*/);
+ assert (ieee754_32to64 (0x3fb4fdf4U as IEEE754_binary32)
/*1.414000e+00*/
+ == (0x3ff69fbe80000000U as IEEE754_binary64) /*1.414000e+00*/);
+ assert (ieee754_32to64 (0xffc00000U as IEEE754_binary32) /*-nan*/
+ == (0xfff8000000000000U as IEEE754_binary64) /*-nan*/);
+ assert (ieee754_32to64 (0x7fc00000U as IEEE754_binary32) /*nan*/
+ == (0x7ff8000000000000U as IEEE754_binary64) /*nan*/);
+ assert (ieee754_32to64 (0x7f800000U as IEEE754_binary32) /*inf*/
+ == (0x7ff0000000000000U as IEEE754_binary64) /*inf*/);
+ },
+ },
];
var ok = pktest_run (tests);
--
2.47.1
[PATCH] pickles/ieee754.pk: add half->single and single->double conversion funcs,
Mohammad-Reza Nabipoor <=