1 /* Test of signbit() substitute.
2    Copyright (C) 2007-2018 Free Software Foundation, Inc.
3 
4    This program is free software: you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation; either version 3 of the License, or
7    (at your option) any later version.
8 
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13 
14    You should have received a copy of the GNU General Public License
15    along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
16 
17 /* Written by Bruno Haible <bruno@clisp.org>, 2007.  */
18 
19 #include <config.h>
20 
21 #include <math.h>
22 
23 /* signbit must be a macro.  */
24 #ifndef signbit
25 # error missing declaration
26 #endif
27 
28 #include <float.h>
29 #include <limits.h>
30 
31 #include "minus-zero.h"
32 #include "infinity.h"
33 #include "macros.h"
34 
35 float zerof = 0.0f;
36 double zerod = 0.0;
37 long double zerol = 0.0L;
38 
39 static void
test_signbitf()40 test_signbitf ()
41 {
42   /* Finite values.  */
43   ASSERT (!signbit (3.141f));
44   ASSERT (!signbit (3.141e30f));
45   ASSERT (!signbit (3.141e-30f));
46   ASSERT (signbit (-2.718f));
47   ASSERT (signbit (-2.718e30f));
48   ASSERT (signbit (-2.718e-30f));
49   /* Zeros.  */
50   ASSERT (!signbit (0.0f));
51   if (1.0f / minus_zerof < 0)
52     ASSERT (signbit (minus_zerof));
53   else
54     ASSERT (!signbit (minus_zerof));
55   /* Infinite values.  */
56   ASSERT (!signbit (Infinityf ()));
57   ASSERT (signbit (- Infinityf ()));
58   /* Quiet NaN.  */
59   (void) signbit (zerof / zerof);
60 #if defined FLT_EXPBIT0_WORD && defined FLT_EXPBIT0_BIT
61   /* Signalling NaN.  */
62   {
63     #define NWORDS \
64       ((sizeof (float) + sizeof (unsigned int) - 1) / sizeof (unsigned int))
65     typedef union { float value; unsigned int word[NWORDS]; } memory_float;
66     memory_float m;
67     m.value = zerof / zerof;
68 # if FLT_EXPBIT0_BIT > 0
69     m.word[FLT_EXPBIT0_WORD] ^= (unsigned int) 1 << (FLT_EXPBIT0_BIT - 1);
70 # else
71     m.word[FLT_EXPBIT0_WORD + (FLT_EXPBIT0_WORD < NWORDS / 2 ? 1 : - 1)]
72       ^= (unsigned int) 1 << (sizeof (unsigned int) * CHAR_BIT - 1);
73 # endif
74     if (FLT_EXPBIT0_WORD < NWORDS / 2)
75       m.word[FLT_EXPBIT0_WORD + 1] |= (unsigned int) 1 << FLT_EXPBIT0_BIT;
76     else
77       m.word[0] |= (unsigned int) 1;
78     (void) signbit (m.value);
79     #undef NWORDS
80   }
81 #endif
82 }
83 
84 static void
test_signbitd()85 test_signbitd ()
86 {
87   /* Finite values.  */
88   ASSERT (!signbit (3.141));
89   ASSERT (!signbit (3.141e30));
90   ASSERT (!signbit (3.141e-30));
91   ASSERT (signbit (-2.718));
92   ASSERT (signbit (-2.718e30));
93   ASSERT (signbit (-2.718e-30));
94   /* Zeros.  */
95   ASSERT (!signbit (0.0));
96   if (1.0 / minus_zerod < 0)
97     ASSERT (signbit (minus_zerod));
98   else
99     ASSERT (!signbit (minus_zerod));
100   /* Infinite values.  */
101   ASSERT (!signbit (Infinityd ()));
102   ASSERT (signbit (- Infinityd ()));
103   /* Quiet NaN.  */
104   (void) signbit (zerod / zerod);
105 #if defined DBL_EXPBIT0_WORD && defined DBL_EXPBIT0_BIT
106   /* Signalling NaN.  */
107   {
108     #define NWORDS \
109       ((sizeof (double) + sizeof (unsigned int) - 1) / sizeof (unsigned int))
110     typedef union { double value; unsigned int word[NWORDS]; } memory_double;
111     memory_double m;
112     m.value = zerod / zerod;
113 # if DBL_EXPBIT0_BIT > 0
114     m.word[DBL_EXPBIT0_WORD] ^= (unsigned int) 1 << (DBL_EXPBIT0_BIT - 1);
115 # else
116     m.word[DBL_EXPBIT0_WORD + (DBL_EXPBIT0_WORD < NWORDS / 2 ? 1 : - 1)]
117       ^= (unsigned int) 1 << (sizeof (unsigned int) * CHAR_BIT - 1);
118 # endif
119     m.word[DBL_EXPBIT0_WORD + (DBL_EXPBIT0_WORD < NWORDS / 2 ? 1 : - 1)]
120       |= (unsigned int) 1 << DBL_EXPBIT0_BIT;
121     (void) signbit (m.value);
122     #undef NWORDS
123   }
124 #endif
125 }
126 
127 static void
test_signbitl()128 test_signbitl ()
129 {
130   /* Finite values.  */
131   ASSERT (!signbit (3.141L));
132   ASSERT (!signbit (3.141e30L));
133   ASSERT (!signbit (3.141e-30L));
134   ASSERT (signbit (-2.718L));
135   ASSERT (signbit (-2.718e30L));
136   ASSERT (signbit (-2.718e-30L));
137   /* Zeros.  */
138   ASSERT (!signbit (0.0L));
139   if (1.0L / minus_zerol < 0)
140     ASSERT (signbit (minus_zerol));
141   else
142     ASSERT (!signbit (minus_zerol));
143   /* Infinite values.  */
144   ASSERT (!signbit (Infinityl ()));
145   ASSERT (signbit (- Infinityl ()));
146   /* Quiet NaN.  */
147   (void) signbit (zerol / zerol);
148 #if defined LDBL_EXPBIT0_WORD && defined LDBL_EXPBIT0_BIT
149   /* Signalling NaN.  */
150   {
151     #define NWORDS \
152       ((sizeof (long double) + sizeof (unsigned int) - 1) / sizeof (unsigned int))
153     typedef union { long double value; unsigned int word[NWORDS]; } memory_long_double;
154 
155 #if defined __powerpc__ && LDBL_MANT_DIG == 106
156     /* This is PowerPC "double double", a pair of two doubles.  Inf and Nan are
157        represented as the corresponding 64-bit IEEE values in the first double;
158        the second is ignored.  Manipulate only the first double.  */
159     #undef NWORDS
160     #define NWORDS \
161       ((sizeof (double) + sizeof (unsigned int) - 1) / sizeof (unsigned int))
162 #endif
163 
164     memory_long_double m;
165     m.value = zerol / zerol;
166 # if LDBL_EXPBIT0_BIT > 0
167     m.word[LDBL_EXPBIT0_WORD] ^= (unsigned int) 1 << (LDBL_EXPBIT0_BIT - 1);
168 # else
169     m.word[LDBL_EXPBIT0_WORD + (LDBL_EXPBIT0_WORD < NWORDS / 2 ? 1 : - 1)]
170       ^= (unsigned int) 1 << (sizeof (unsigned int) * CHAR_BIT - 1);
171 # endif
172     m.word[LDBL_EXPBIT0_WORD + (LDBL_EXPBIT0_WORD < NWORDS / 2 ? 1 : - 1)]
173       |= (unsigned int) 1 << LDBL_EXPBIT0_BIT;
174     (void) signbit (m.value);
175     #undef NWORDS
176   }
177 #endif
178 }
179 
180 int
main()181 main ()
182 {
183   test_signbitf ();
184   test_signbitd ();
185   test_signbitl ();
186   return 0;
187 }
188