poke-devel
[Top][All Lists]
Advanced

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

Re: [PATCH] pickles: add new pickle for floating-point numbers


From: Jose E. Marchesi
Subject: Re: [PATCH] pickles: add new pickle for floating-point numbers
Date: Sun, 08 Jan 2023 00:23:20 +0100
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/28.0.50 (gnu/linux)


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

OK for master.
Thanks to you and to apache2!

>
> 2022-01-07  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.
> ---
>  ChangeLog                              |   8 ++
>  pickles/Makefile.am                    |   2 +-
>  pickles/ieee754.pk                     |  70 +++++++++++++++
>  testsuite/Makefile.am                  |   1 +
>  testsuite/poke.pickles/ieee754-test.pk | 120 +++++++++++++++++++++++++
>  5 files changed, 200 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 2a35968c..d650a133 100644
> --- a/ChangeLog
> +++ b/ChangeLog
> @@ -1,3 +1,11 @@
> +2022-01-07  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-07  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 f2b6ca50..9de25565 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..9fd65885
> --- /dev/null
> +++ b/pickles/ieee754.pk
> @@ -0,0 +1,70 @@
> +/* 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.
> +
> +    computed string str;
> +
> +    method get_str = string: { return format_f32 (sign:::exp:::frac); }
> +    method set_str = (string s) void: { raise E_inval; }
> +
> +    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; }
> +  };
> +
> +type IEEE754_binary64 =
> +  struct int<64>
> +  {
> +    uint<1> sign;
> +    uint<11> exp;
> +    uint<52> frac; // aka significand, aka mantissa.
> +
> +    computed string str;
> +
> +    method get_str = string: { return format_f64 (sign:::exp:::frac); }
> +    method set_str = (string s) void: { raise E_inval; }
> +
> +    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; }
> +  };
> +
> +type Float16 = IEEE754_binary16;
> +type Float32 = IEEE754_binary32;
> +type Float64 = IEEE754_binary64;
> diff --git a/testsuite/Makefile.am b/testsuite/Makefile.am
> index 3b90344a..eb361391 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..f6f27cae
> --- /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 (one.str == "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 (minus_two.str == "-2.0000000");
> +
> +        var random = 0x42288659 as Float32;
> +
> +        assert (random.sign == 0);
> +        assert (random.exp == 0x84);
> +        assert (random.frac == 0x288659);
> +        assert (random.str == "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 (pi.str == "3.141592653590000");
> +      },
> +  },
> +];
> +
> +var ok = pktest_run (tests);
> +
> +close (data);
> +exit(ok ? 0 : 1);



reply via email to

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