From 2f364b8ddc6729cb93f550cbcb33e50292bb4aef Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Fri, 13 Oct 2023 13:46:17 +0200 Subject: [PATCH] signed-snan: New module. * lib/snan.h (construct_SNaNf): New function, extracted from SNaNf. (SNaNf): Use it. (construct_SNaNd): New function, extracted from SNaNd. (SNaNd): Use it. (construct_SNaNl): New function, extracted from SNaNl. (SNaNl): Use it. * lib/signed-snan.h: New file. * modules/signed-snan: New file. --- ChangeLog | 12 +++++++ lib/signed-snan.h | 81 +++++++++++++++++++++++++++++++++++++++++++++ lib/snan.h | 36 +++++++++++++++----- modules/signed-snan | 25 ++++++++++++++ 4 files changed, 145 insertions(+), 9 deletions(-) create mode 100644 lib/signed-snan.h create mode 100644 modules/signed-snan diff --git a/ChangeLog b/ChangeLog index 7a06938f21..710636aff6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2023-10-13 Bruno Haible + + signed-snan: New module. + * lib/snan.h (construct_SNaNf): New function, extracted from SNaNf. + (SNaNf): Use it. + (construct_SNaNd): New function, extracted from SNaNd. + (SNaNd): Use it. + (construct_SNaNl): New function, extracted from SNaNl. + (SNaNl): Use it. + * lib/signed-snan.h: New file. + * modules/signed-snan: New file. + 2023-10-13 Bruno Haible signed-nan: New module, renamed from qnan. diff --git a/lib/signed-snan.h b/lib/signed-snan.h new file mode 100644 index 0000000000..f275467567 --- /dev/null +++ b/lib/signed-snan.h @@ -0,0 +1,81 @@ +/* Macros for signalling not-a-number. + Copyright (C) 2023 Free Software Foundation, Inc. + + 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 . */ + +#ifndef _SIGNED_SNAN_H +#define _SIGNED_SNAN_H + +#include "signed-nan.h" +#include "snan.h" + + +#if HAVE_SNANF + +/* Returns a signalling 'float' NaN with sign bit == 0. */ +_GL_UNUSED static float +positive_SNaNf () +{ + return construct_SNaNf (positive_NaNf ()); +} + +/* Returns a signalling 'float' NaN with sign bit == 1. */ +_GL_UNUSED static float +negative_SNaNf () +{ + return construct_SNaNf (negative_NaNf ()); +} + +#endif + + +#if HAVE_SNAND + +/* Returns a signalling 'double' NaN with sign bit == 0. */ +_GL_UNUSED static double +positive_SNaNd () +{ + return construct_SNaNd (positive_NaNd ()); +} + +/* Returns a signalling 'double' NaN with sign bit == 1. */ +_GL_UNUSED static double +negative_SNaNd () +{ + return construct_SNaNd (negative_NaNd ()); +} + +#endif + + +#if HAVE_SNANL + +/* Returns a signalling 'long double' NaN with sign bit == 0. */ +_GL_UNUSED static long double +positive_SNaNl () +{ + return construct_SNaNl (positive_NaNl ()); +} + +/* Returns a signalling 'long double' NaN with sign bit == 1. */ +_GL_UNUSED static long double +negative_SNaNl () +{ + return construct_SNaNl (negative_NaNl ()); +} + +#endif + + +#endif /* _SIGNED_SNAN_H */ diff --git a/lib/snan.h b/lib/snan.h index 88950437c8..2e271055c5 100644 --- a/lib/snan.h +++ b/lib/snan.h @@ -45,15 +45,14 @@ # define HAVE_SNANF 1 -/* Returns a signalling 'float' NaN. */ _GL_UNUSED static float -SNaNf () +construct_SNaNf (float quiet_value) { #define NWORDS \ ((sizeof (float) + sizeof (unsigned int) - 1) / sizeof (unsigned int)) typedef union { float value; unsigned int word[NWORDS]; } memory_float; memory_float m; - m.value = NaNf (); + m.value = quiet_value; /* Turn the quiet NaN into a signalling NaN. */ #if FLT_EXPBIT0_BIT > 0 m.word[FLT_EXPBIT0_WORD] ^= (unsigned int) 1 << (FLT_EXPBIT0_BIT - 1); @@ -70,6 +69,13 @@ SNaNf () return m.value; } +/* Returns a signalling 'float' NaN. */ +_GL_UNUSED static float +SNaNf () +{ + return construct_SNaNf (NaNf ()); +} + #endif @@ -77,15 +83,14 @@ SNaNf () # define HAVE_SNAND 1 -/* Returns a signalling 'double' NaN. */ _GL_UNUSED static double -SNaNd () +construct_SNaNd (double quiet_value) { #define NWORDS \ ((sizeof (double) + sizeof (unsigned int) - 1) / sizeof (unsigned int)) typedef union { double value; unsigned int word[NWORDS]; } memory_double; memory_double m; - m.value = NaNd (); + m.value = quiet_value; /* Turn the quiet NaN into a signalling NaN. */ #if DBL_EXPBIT0_BIT > 0 m.word[DBL_EXPBIT0_WORD] ^= (unsigned int) 1 << (DBL_EXPBIT0_BIT - 1); @@ -100,6 +105,13 @@ SNaNd () return m.value; } +/* Returns a signalling 'double' NaN. */ +_GL_UNUSED static double +SNaNd () +{ + return construct_SNaNd (NaNd ()); +} + #endif @@ -107,9 +119,8 @@ SNaNd () # define HAVE_SNANL 1 -/* Returns a signalling 'long double' NaN. */ _GL_UNUSED static long double -SNaNl () +construct_SNaNl (long double quiet_value) { /* A bit pattern that is different from a Quiet NaN. With a bit of luck, it's a Signalling NaN. */ @@ -118,7 +129,7 @@ SNaNl () typedef union { unsigned int word[NWORDS]; long double value; } memory_long_double; memory_long_double m; - m.value = NaNl (); + m.value = quiet_value; #if defined __powerpc__ && LDBL_MANT_DIG == 106 /* This is PowerPC "double double", a pair of two doubles. Inf and NaN are represented as the corresponding 64-bit IEEE values in the first double; @@ -143,6 +154,13 @@ SNaNl () return m.value; } +/* Returns a signalling 'long double' NaN. */ +_GL_UNUSED static long double +SNaNl () +{ + return construct_SNaNl (NaNl ()); +} + #endif diff --git a/modules/signed-snan b/modules/signed-snan new file mode 100644 index 0000000000..492d817d48 --- /dev/null +++ b/modules/signed-snan @@ -0,0 +1,25 @@ +Description: +Macros for signalling not-a-number. + +Files: +lib/signed-snan.h + +Depends-on: +signed-nan +snan + +configure.ac: + +Makefile.am: +lib_SOURCES += signed-snan.h + +Include: +"signed-snan.h" + +Link: + +License: +GPL + +Maintainer: +all -- 2.39.5