poke-devel
[Top][All Lists]
Advanced

[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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]