]> Savannah Git Hosting - gnulib.git/commitdiff
snan: Comments.
authorBruno Haible <bruno@clisp.org>
Thu, 12 Oct 2023 20:15:44 +0000 (22:15 +0200)
committerBruno Haible <bruno@clisp.org>
Thu, 12 Oct 2023 21:54:48 +0000 (23:54 +0200)
* lib/snan.h: Add more comments.

ChangeLog
lib/snan.h

index ede627dca4a7fa9eadcd2fea108f7b1c333bbc2e..f0f23b8bbb92e9e95233264180ebad95f630cc38 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2023-10-12  Bruno Haible  <bruno@clisp.org>
+
+       snan: Comments.
+       * lib/snan.h: Add more comments.
+
 2023-10-12  Bruno Haible  <bruno@clisp.org>
 
        snan: New module.
index 5dd4dd6f9e1e12d9fcfdaf6fcea64c04700b0020..88950437c8040525802b8eda192fcd126b2260fa 100644 (file)
 #include "nan.h"
 
 
+/* The bit that distinguishes a quiet NaN from a signalling NaN is, according to
+   <https://en.wikipedia.org/wiki/NaN#Encoding>, the most significant bit of the
+   mantissa field.
+   According to <https://en.wikipedia.org/wiki/IEEE_754#Formats>, this is the
+   next bit, right below the bit 0 of the exponent.
+   This bit is
+     *  == 0 to indicate a quiet NaN or Infinity,
+        == 1 to indicate a signalling NaN,
+        on these CPUs: hppa, mips.
+     *  == 1 to indicate a quiet NaN,
+        == 0 to indicate a signalling NaN or Infinity,
+        on all other CPUs.
+        On these platforms, additionally a signalling NaN must have some other
+        mantissa bit == 1, because when all exponent bits are == 1 and all
+        mantissa bits are == 0, the number denotes ±Infinity.  */
+
+
 #if defined FLT_EXPBIT0_WORD && defined FLT_EXPBIT0_BIT
 
 # define HAVE_SNANF 1
@@ -37,15 +54,17 @@ SNaNf ()
   typedef union { float value; unsigned int word[NWORDS]; } memory_float;
   memory_float m;
   m.value = NaNf ();
- #if FLT_EXPBIT0_BIT > 0
+  /* 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);
- #else
 #else
     m.word[FLT_EXPBIT0_WORD + (FLT_EXPBIT0_WORD < NWORDS / 2 ? 1 : - 1)]
       ^= (unsigned int) 1 << (sizeof (unsigned int) * CHAR_BIT - 1);
- #endif
-  if (FLT_EXPBIT0_WORD < NWORDS / 2)
+  #endif
+  /* Set some arbitrary mantissa bit.  */
+  if (FLT_EXPBIT0_WORD < NWORDS / 2) /* NWORDS > 1 and big endian */
     m.word[FLT_EXPBIT0_WORD + 1] |= (unsigned int) 1 << FLT_EXPBIT0_BIT;
-  else
+  else /* NWORDS == 1 or little endian */
     m.word[0] |= (unsigned int) 1;
   #undef NWORDS
   return m.value;
@@ -67,12 +86,14 @@ SNaNd ()
   typedef union { double value; unsigned int word[NWORDS]; } memory_double;
   memory_double m;
   m.value = NaNd ();
+  /* 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);
   #else
     m.word[DBL_EXPBIT0_WORD + (DBL_EXPBIT0_WORD < NWORDS / 2 ? 1 : - 1)]
       ^= (unsigned int) 1 << (sizeof (unsigned int) * CHAR_BIT - 1);
   #endif
+  /* Set some arbitrary mantissa bit.  */
   m.word[DBL_EXPBIT0_WORD + (DBL_EXPBIT0_WORD < NWORDS / 2 ? 1 : - 1)]
     |= (unsigned int) 1 << DBL_EXPBIT0_BIT;
   #undef NWORDS
@@ -107,12 +128,14 @@ SNaNl ()
   #else
     #define HNWORDS NWORDS
   #endif
+  /* Turn the quiet NaN into a signalling NaN.  */
   #if LDBL_EXPBIT0_BIT > 0
     m.word[LDBL_EXPBIT0_WORD] ^= (unsigned int) 1 << (LDBL_EXPBIT0_BIT - 1);
   #else
     m.word[LDBL_EXPBIT0_WORD + (LDBL_EXPBIT0_WORD < HNWORDS / 2 ? 1 : - 1)]
       ^= (unsigned int) 1 << (sizeof (unsigned int) * CHAR_BIT - 1);
   #endif
+  /* Set some arbitrary mantissa bit.  */
   m.word[LDBL_EXPBIT0_WORD + (LDBL_EXPBIT0_WORD < HNWORDS / 2 ? 1 : - 1)]
     |= (unsigned int) 1 << LDBL_EXPBIT0_BIT;
   #undef HNWORDS