poke-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH v2 2/2] pickles: add new pickle for floating-point numbers


From: Mohammad-Reza Nabipoor
Subject: [PATCH v2 2/2] pickles: add new pickle for floating-point numbers
Date: Mon, 9 Jan 2023 00:58:00 +0100

This commit adds a rudimentary pickle for working with
floating-point numbers.  The pickle and tests were initially
written by apache2.

2022-01-09  Mohammad-Reza Nabipoor  <mnabipoor@gnu.org>

        * pickles/ieee754.pk: New pickle for IEEE 754 floating-point
        numbers based on initial code from apache2.
        * pickles/Makefile.am (dist_pickles_DATA): Add new pickle.
        * testsuite/poke.pickles/ieee754-test.pk: New test.
        * testsuite/Makefile.am (EXTRAD_DIST): Update.
---

Hello Jose.

Yes, you've already accepted it, but I wanted to send the updated version
to the mailing list :)



 ChangeLog                              |   8 ++
 pickles/Makefile.am                    |   2 +-
 pickles/ieee754.pk                     |  64 +++++++++++++
 testsuite/Makefile.am                  |   1 +
 testsuite/poke.pickles/ieee754-test.pk | 120 +++++++++++++++++++++++++
 5 files changed, 194 insertions(+), 1 deletion(-)
 create mode 100644 pickles/ieee754.pk
 create mode 100644 testsuite/poke.pickles/ieee754-test.pk

diff --git a/ChangeLog b/ChangeLog
index 813f70d5..0e723c1e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2022-01-09  Mohammad-Reza Nabipoor  <mnabipoor@gnu.org>
+
+       * pickles/ieee754.pk: New pickle for IEEE 754 floating-point
+       numbers based on initial code from apache2.
+       * pickles/Makefile.am (dist_pickles_DATA): Add new pickle.
+       * testsuite/poke.pickles/ieee754-test.pk: New test.
+       * testsuite/Makefile.am (EXTRA_DIST): Update.
+
 2022-01-09  Mohammad-Reza Nabipoor  <mnabipoor@gnu.org>
 
        * libpoke/pkl-insn.def (formatf32): Add new instruction.
diff --git a/pickles/Makefile.am b/pickles/Makefile.am
index a39fb7e9..49b8df6b 100644
--- a/pickles/Makefile.am
+++ b/pickles/Makefile.am
@@ -26,4 +26,4 @@ dist_pickles_DATA = elf-common.pk elf-64.pk elf-32.pk elf.pk 
ctf.pk ctf-dump.pk
                     openpgp.pk search.pk riscv.pk coff.pk coff-i386.pk 
coff-aarch64.pk \
                     pe.pk pe-amd64.pk pe-arm.pk pe-arm64.pk pe-i386.pk 
pe-ia64.pk \
                     pe-m32r.pk pe-mips.pk pe-ppc.pk pe-sh3.pk pe-riscv.pk 
pe-debug.pk \
-                   uuid.pk redoxfs.pk pcap.pk
+                   uuid.pk redoxfs.pk pcap.pk ieee754.pk
diff --git a/pickles/ieee754.pk b/pickles/ieee754.pk
new file mode 100644
index 00000000..b7dbe044
--- /dev/null
+++ b/pickles/ieee754.pk
@@ -0,0 +1,64 @@
+/* ieee754.pk - IEEE Standard for Floating-Point Arithmetic.  */
+
+/* Copyright (C) 2022-2023 The poke authors.  */
+
+/* This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+type IEEE754_binary16 =
+  struct int<16>
+  {
+    uint<1> sign;
+    uint<5> exp;
+    uint<10> frac; // aka significand, aka mantissa.
+
+    method is_nan_p  = int: { return exp == 0x1f && frac != 0; }
+    method is_snan_p = int: { return exp == 0x1f && (frac & 0x200U); }
+    method is_qnan_p = int: { return exp == 0x1f && !(frac & 0x200U); }
+    method is_inf_p  = int: { return exp == 0x1f && frac == 0; }
+  };
+
+type IEEE754_binary32 =
+  struct int<32>
+  {
+    uint<1> sign;
+    uint<8> exp;
+    uint<23> frac; // aka significand, aka mantissa.
+
+    method is_nan_p  = int: { return exp == 0xff && frac != 0; }
+    method is_snan_p = int: { return exp == 0xff && (frac & 0x400000U); }
+    method is_qnan_p = int: { return exp == 0xff && !(frac & 0x400000U); }
+    method is_inf_p  = int: { return exp == 0xff && frac == 0; }
+
+    method _print = void: { printf ("#<%f32d>", sign:::exp:::frac); }
+  };
+
+type IEEE754_binary64 =
+  struct int<64>
+  {
+    uint<1> sign;
+    uint<11> exp;
+    uint<52> frac; // aka significand, aka mantissa.
+
+    method is_nan_p  = int: { return exp == 0x7ff && frac != 0; }
+    method is_snan_p = int: { return exp == 0x7ff && (frac & 
0x4000000000000U); }
+    method is_qnan_p = int: { return exp == 0x7ff && !(frac & 
0x4000000000000U); }
+    method is_inf_p  = int: { return exp == 0x7ff && frac == 0; }
+
+    method _print = void: { printf ("#<%f64d>", sign:::exp:::frac); }
+  };
+
+type Float16 = IEEE754_binary16;
+type Float32 = IEEE754_binary32;
+type Float64 = IEEE754_binary64;
diff --git a/testsuite/Makefile.am b/testsuite/Makefile.am
index 3de991c2..979665bf 100644
--- a/testsuite/Makefile.am
+++ b/testsuite/Makefile.am
@@ -610,6 +610,7 @@ EXTRA_DIST = \
   poke.pickles/uuid-test.pk \
   poke.pickles/redoxfs-test.pk \
   poke.pickles/pcap-test.pk \
+  poke.pickles/ieee754-test.pk \
   poke.pkl/pkl.exp \
   poke.pkl/postincr-1.pk \
   poke.pkl/postincr-2.pk \
diff --git a/testsuite/poke.pickles/ieee754-test.pk 
b/testsuite/poke.pickles/ieee754-test.pk
new file mode 100644
index 00000000..6192790d
--- /dev/null
+++ b/testsuite/poke.pickles/ieee754-test.pk
@@ -0,0 +1,120 @@
+/* ieee754-test.pk - Tests for the IEEE 754 pickle.  */
+
+/* Copyright (C) 2022-2023 The poke authors.  */
+
+/* This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+load pktest;
+load ieee754;
+
+var data = open("*data*");
+
+var tests = [
+  PkTest {
+    name = "binary16",
+    func = lambda (string name) void:
+      {
+        var one = 0x3c00 as Float16;
+
+        assert (one.sign == 0);
+        assert (one.exp == 0xf);
+        assert (one.frac == 0);
+        assert (!one.is_inf_p);
+        assert (!one.is_nan_p);
+
+        var minus_two = 0xc000 as Float16;
+
+        assert (minus_two.sign == 1);
+        assert (minus_two.exp == 0x10); // 2^(16-15) = 2^1 = 2
+        assert (minus_two.frac == 0);
+        assert (!minus_two.is_inf_p);
+        assert (!minus_two.is_nan_p);
+
+        var random = 0x5144 as Float16;
+
+        assert (random.sign == 0);
+        assert (random.exp == 0x14); // 42
+        assert (random.frac == 0x144); // .125
+        assert (!random.is_inf_p);
+        assert (!random.is_nan_p);
+
+        var posinf = 0b0111110000000000 as Float16;
+
+        assert (posinf.is_inf_p);
+        assert (!posinf.is_nan_p);
+      },
+  },
+  PkTest {
+    name = "binary32",
+    func = lambda (string name) void:
+      {
+        var one = 0x3f800000 as Float32;
+
+        assert (one.sign == 0);
+        assert (one.exp == 127); // 2^(127-127) == 2^0 == 1
+        assert (one.frac == 0);
+        assert (format ("%f32d", +one) == "1.0000000");
+
+        var minus_two = 0xc0000000 as Float32;
+
+        assert (minus_two.sign == 1);
+        assert (minus_two.exp == 128); // 2^(128-127) == 2^1 == 1
+        assert (minus_two.frac == 0);
+        assert (format ("%f32d", +minus_two) == "-2.0000000");
+
+        var random = 0x42288659 as Float32;
+
+        assert (random.sign == 0);
+        assert (random.exp == 0x84);
+        assert (random.frac == 0x288659);
+        assert (format ("%f32d", +random) == "42.1311989");
+
+        uint<8>[4] @ data : 0#B = [ 0xa4UB, 0x70UB, 0x45UB, 0x41UB];
+
+        type little_32 = struct { little uint<32> f; };
+        var l32 = (little_32 @ data : 0#B).f as Float32;
+
+        assert (l32.sign == 0);
+        assert (l32.exp - 127 == 3);
+        assert (l32.frac == 0x4570a4);
+
+        // Reverse the four bytes:
+        uint<8>[4] @ data : 0#B = [ 0x41UB, 0x45UB, 0x70UB, 0xa4UB];
+
+        type big_32 = struct { big uint<32> f; };
+        var b32 = (big_32 @ data : 0#B).f as Float32;
+
+        assert (b32 == l32);
+      },
+  },
+    PkTest {
+    name = "binary64",
+    func = lambda (string name) void:
+      {
+        var pi = 0x400921fb54442eeaUL as Float64;
+
+        assert (pi.sign == 0);
+        assert (pi.exp == 0b10000000000);
+        assert (pi.frac
+                == 0b1001001000011111101101010100010001000010111011101010U);
+        assert (format ("%f64d", +pi) == "3.141592653590000");
+      },
+  },
+];
+
+var ok = pktest_run (tests);
+
+close (data);
+exit(ok ? 0 : 1);
-- 
2.39.0




reply via email to

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