c4f9731413117a84122f81d66416cfa2ec605171
[kopensolaris-gnu/glibc.git] / math / test-misc.c
1 /* Miscellaneous tests which don't fit anywhere else.
2    Copyright (C) 2000 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4
5    The GNU C Library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Library General Public License as
7    published by the Free Software Foundation; either version 2 of the
8    License, or (at your option) any later version.
9
10    The GNU C Library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Library General Public License for more details.
14
15    You should have received a copy of the GNU Library General Public
16    License along with the GNU C Library; see the file COPYING.LIB.  If not,
17    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18    Boston, MA 02111-1307, USA.  */
19
20 #include <fenv.h>
21 #include <math.h>
22 #include <stdio.h>
23 #include <string.h>
24
25
26 int
27 main (void)
28 {
29   int result = 0;
30
31 #ifndef NO_LONG_DOUBLE
32   {
33     long double x = 0x100000001ll + (long double) 0.5;
34     long double q;
35     long double r;
36
37     r = modfl (x, &q);
38     if (q != (long double) 0x100000001ll || r != 0.5)
39       {
40         printf ("modfl (%Lg, ...) failed\n", x);
41         result = 1;
42       }
43   }
44
45 # if __GNUC__ >= 3 || __GNUC_MINOR__ >= 96
46   {
47     long double x;
48     long double m;
49     long double r;
50     int e;
51     int i;
52
53 #  if LDBL_MANT_DIG == 64
54     m = 0xf.fffffffffffffffp-4L;
55 #  elif LDBL_MANT_DIG == 113
56     m = 0x1.ffffffffffffffffffffffffffffp-1L;
57 #  else
58 #   error "Please adjust"
59 #  endif
60
61     for (i = LDBL_MAX_EXP, x = LDBL_MAX; i >= LDBL_MIN_EXP; --i, x /= 2.0L)
62       {
63         printf ("2^%d: ", i);
64
65         r = frexpl (x, &e);
66         if (r != m)
67           {
68             printf ("mantissa incorrect: %.20La\n", r);
69             result = 1;
70             continue;
71           }
72         if (e != i)
73           {
74             printf ("exponent wrong %d (%.20Lg)\n", e, x);
75             result = 1;
76             continue;
77           }
78         puts ("ok");
79       }
80   }
81 # endif
82
83 #if 0
84   {
85     int e;
86     long double r = frexpl (LDBL_MIN * LDBL_EPSILON, &e);
87
88     if (r != 0.5)
89       {
90         printf ("frexpl (LDBL_MIN * LDBL_EPSILON, ...): mantissa wrong: %Lg\n",
91                 r);
92         result = 1;
93       }
94     else if (e != -16444)
95       {
96         printf ("frexpl (LDBL_MIN * LDBL_EPSILON, ...): exponent wrong: %d\n",
97                 e);
98         result = 1;
99       }
100   }
101 #endif
102 #endif
103
104   {
105     double x = 0x100000001ll + (double) 0.5;
106     double q;
107     double r;
108
109     r = modf (x, &q);
110     if (q != (double) 0x100000001ll || r != 0.5)
111       {
112         printf ("modf (%g, ...) failed\n", x);
113         result = 1;
114       }
115   }
116
117   {
118     float f;
119
120     f = FLT_MIN;
121     if (fpclassify (f) != FP_NORMAL)
122       {
123         printf ("fpclassify (FLT_MIN) failed: %d\n", fpclassify (f));
124         result = 1;
125       }
126     f = nextafterf (f, FLT_MIN / 2.0f);
127     if (fpclassify (f) != FP_SUBNORMAL)
128       {
129         printf ("fpclassify (FLT_MIN-epsilon) failed: %d\n", fpclassify (f));
130         result = 1;
131       }
132     f = nextafterf (f, FLT_MIN);
133     if (fpclassify (f) != FP_NORMAL)
134       {
135         printf ("fpclassify (FLT_MIN-epsilon+epsilong) failed: %d\n",
136                 fpclassify (f));
137         result = 1;
138       }
139
140     f = -FLT_MIN;
141     if (fpclassify (f) != FP_NORMAL)
142       {
143         printf ("fpclassify (-FLT_MIN) failed: %d\n", fpclassify (f));
144         result = 1;
145       }
146     f = nextafterf (f, -FLT_MIN / 2.0f);
147     if (fpclassify (f) != FP_SUBNORMAL)
148       {
149         printf ("fpclassify (-FLT_MIN-epsilon) failed: %d\n", fpclassify (f));
150         result = 1;
151       }
152     f = nextafterf (f, -FLT_MIN);
153     if (fpclassify (f) != FP_NORMAL)
154       {
155         printf ("fpclassify (-FLT_MIN-epsilon+epsilong) failed: %d\n",
156                 fpclassify (f));
157         result = 1;
158       }
159   }
160   {
161     double d;
162
163     d = DBL_MIN;
164     if (fpclassify (d) != FP_NORMAL)
165       {
166         printf ("fpclassify (DBL_MIN) failed: %d\n", fpclassify (d));
167         result = 1;
168       }
169     d = nextafter (d, DBL_MIN / 2.0);
170     if (fpclassify (d) != FP_SUBNORMAL)
171       {
172         printf ("fpclassify (DBL_MIN-epsilon) failed: %d\n", fpclassify (d));
173         result = 1;
174       }
175     d = nextafter (d, DBL_MIN);
176     if (fpclassify (d) != FP_NORMAL)
177       {
178         printf ("fpclassify (DBL_MIN-epsilon+epsilon) failed: %d\n",
179                 fpclassify (d));
180         result = 1;
181       }
182
183     d = -DBL_MIN;
184     if (fpclassify (d) != FP_NORMAL)
185       {
186         printf ("fpclassify (-DBL_MIN) failed: %d\n", fpclassify (d));
187         result = 1;
188       }
189     d = nextafter (d, -DBL_MIN / 2.0);
190     if (fpclassify (d) != FP_SUBNORMAL)
191       {
192         printf ("fpclassify (-DBL_MIN-epsilon) failed: %d\n", fpclassify (d));
193         result = 1;
194       }
195     d = nextafter (d, -DBL_MIN);
196     if (fpclassify (d) != FP_NORMAL)
197       {
198         printf ("fpclassify (-DBL_MIN-epsilon+epsilon) failed: %d\n",
199                 fpclassify (d));
200         result = 1;
201       }
202   }
203 #ifndef NO_LONG_DOUBLE
204   {
205     long double ld;
206
207     ld = LDBL_MIN;
208     if (fpclassify (ld) != FP_NORMAL)
209       {
210         printf ("fpclassify (LDBL_MIN) failed: %d\n", fpclassify (ld));
211         result = 1;
212       }
213     ld = nextafterl (ld, LDBL_MIN / 2.0);
214     if (fpclassify (ld) != FP_SUBNORMAL)
215       {
216         printf ("fpclassify (LDBL_MIN-epsilon) failed: %d (%La)\n",
217                 fpclassify (ld), ld);
218         result = 1;
219       }
220     ld = nextafterl (ld, LDBL_MIN);
221     if (fpclassify (ld) != FP_NORMAL)
222       {
223         printf ("fpclassify (LDBL_MIN-epsilon+epsilon) failed: %d (%La)\n",
224                 fpclassify (ld), ld);
225         result = 1;
226       }
227
228     ld = -LDBL_MIN;
229     if (fpclassify (ld) != FP_NORMAL)
230       {
231         printf ("fpclassify (-LDBL_MIN) failed: %d\n", fpclassify (ld));
232         result = 1;
233       }
234     ld = nextafterl (ld, -LDBL_MIN / 2.0);
235     if (fpclassify (ld) != FP_SUBNORMAL)
236       {
237         printf ("fpclassify (-LDBL_MIN-epsilon) failed: %d (%La)\n",
238                 fpclassify (ld), ld);
239         result = 1;
240       }
241     ld = nextafterl (ld, -LDBL_MIN);
242     if (fpclassify (ld) != FP_NORMAL)
243       {
244         printf ("fpclassify (-LDBL_MIN-epsilon+epsilon) failed: %d (%La)\n",
245                 fpclassify (ld), ld);
246         result = 1;
247       }
248   }
249 #endif
250
251   if (! isnormal (FLT_MIN))
252     {
253       puts ("isnormal (FLT_MIN) failed");
254       result = 1;
255     }
256   if (! isnormal (DBL_MIN))
257     {
258       puts ("isnormal (DBL_MIN) failed");
259       result = 1;
260     }
261 #ifndef NO_LONG_DOUBLE
262   if (! isnormal (LDBL_MIN))
263     {
264       puts ("isnormal (LDBL_MIN) failed");
265       result = 1;
266     }
267 #endif
268
269 #ifdef __i386__
270   /* This is a test for the strange long doubles in x86 FPUs.  */
271   {
272     union
273     {
274       char b[10];
275       long double d;
276     } u =
277       { .b = { 0, 0, 0, 0, 0, 0, 0, 0x80, 0, 0 } };
278
279     if (fpclassify (u.d) != FP_NORMAL)
280       {
281         printf ("fpclassify (0x00008000000000000000) failed: %d (%Lg)\n",
282                 fpclassify (u.d), u.d);
283         result = 1;
284       }
285   }
286
287   /* Special NaNs in x86 long double.  Test for scalbl.  */
288   {
289     union
290     {
291       char b[10];
292       long double d;
293     } u =
294       { .b = { 0, 1, 0, 0, 0, 0, 0, 0xc0, 0xff, 0x7f } };
295     long double r;
296
297     r = scalbl (u.d, 0.0);
298     if (!isnan (r))
299       {
300         puts ("scalbl(NaN, 0) does not return NaN");
301         result = 1;
302       }
303     else if (memcmp (&r, &u.d, sizeof (double)) != 0)
304       {
305         puts ("scalbl(NaN, 0) does not return the same NaN");
306         result = 1;
307       }
308   }
309 #endif
310
311 #ifndef NO_LONG_DOUBLE
312   {
313     long double r;
314
315     feclearexcept (FE_ALL_EXCEPT);
316     r = scalbl (LDBL_MIN, 2147483647);
317     if (! isinf (r))
318       {
319         puts ("scalbl (LDBL_MIN, 2147483647) does not return Inf");
320         result = 1;
321       }
322     else if (signbit (r) != 0)
323       {
324         puts ("scalbl (LDBL_MIN, 2147483647) returns -Inf");
325         result = 1;
326       }
327     else if (fetestexcept (FE_UNDERFLOW))
328       {
329         puts ("scalbl(NaN, 0) raises underflow exception");
330         result = 1;
331       }
332
333     feclearexcept (FE_ALL_EXCEPT);
334     r = scalbl (LDBL_MAX, -2147483647);
335     if (r != 0.0)
336       {
337         puts ("scalbl (LDBL_MAX, -2147483647) does not return 0");
338         result = 1;
339       }
340     else if (signbit (r) != 0)
341       {
342         puts ("scalbl (LDBL_MAX, -2147483647) returns -Inf");
343         result = 1;
344       }
345     else if (fetestexcept (FE_OVERFLOW))
346       {
347         puts ("scalbl(NaN, 0) raises overflow exception");
348         result = 1;
349       }
350   }
351 #endif
352
353   return result;
354 }