Yet more tests for nextafter.
[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     f = FLT_MAX;
161     if (fpclassify (f) != FP_NORMAL)
162       {
163         printf ("fpclassify (FLT_MAX) failed: %d\n", fpclassify (f));
164         result = 1;
165       }
166     f = nextafterf (f, INFINITY);
167     if (fpclassify (f) != FP_INFINITE)
168       {
169         printf ("fpclassify (FLT_MAX+epsilon) failed: %d\n", fpclassify (f));
170         result = 1;
171       }
172
173     f = -FLT_MAX;
174     if (fpclassify (f) != FP_NORMAL)
175       {
176         printf ("fpclassify (-FLT_MAX) failed: %d\n", fpclassify (f));
177         result = 1;
178       }
179     f = nextafterf (f, -INFINITY);
180     if (fpclassify (f) != FP_INFINITE)
181       {
182         printf ("fpclassify (-FLT_MAX-epsilon) failed: %d\n", fpclassify (f));
183         result = 1;
184       }
185   }
186   {
187     double d;
188
189     d = DBL_MIN;
190     if (fpclassify (d) != FP_NORMAL)
191       {
192         printf ("fpclassify (DBL_MIN) failed: %d\n", fpclassify (d));
193         result = 1;
194       }
195     d = nextafter (d, DBL_MIN / 2.0);
196     if (fpclassify (d) != FP_SUBNORMAL)
197       {
198         printf ("fpclassify (DBL_MIN-epsilon) failed: %d\n", fpclassify (d));
199         result = 1;
200       }
201     d = nextafter (d, DBL_MIN);
202     if (fpclassify (d) != FP_NORMAL)
203       {
204         printf ("fpclassify (DBL_MIN-epsilon+epsilon) failed: %d\n",
205                 fpclassify (d));
206         result = 1;
207       }
208
209     d = -DBL_MIN;
210     if (fpclassify (d) != FP_NORMAL)
211       {
212         printf ("fpclassify (-DBL_MIN) failed: %d\n", fpclassify (d));
213         result = 1;
214       }
215     d = nextafter (d, -DBL_MIN / 2.0);
216     if (fpclassify (d) != FP_SUBNORMAL)
217       {
218         printf ("fpclassify (-DBL_MIN-epsilon) failed: %d\n", fpclassify (d));
219         result = 1;
220       }
221     d = nextafter (d, -DBL_MIN);
222     if (fpclassify (d) != FP_NORMAL)
223       {
224         printf ("fpclassify (-DBL_MIN-epsilon+epsilon) failed: %d\n",
225                 fpclassify (d));
226         result = 1;
227       }
228
229     d = DBL_MAX;
230     if (fpclassify (d) != FP_NORMAL)
231       {
232         printf ("fpclassify (DBL_MAX) failed: %d\n", fpclassify (d));
233         result = 1;
234       }
235     d = nextafter (d, INFINITY);
236     if (fpclassify (d) != FP_INFINITE)
237       {
238         printf ("fpclassify (DBL_MAX+epsilon) failed: %d\n", fpclassify (d));
239         result = 1;
240       }
241
242     d = -DBL_MAX;
243     if (fpclassify (d) != FP_NORMAL)
244       {
245         printf ("fpclassify (-DBL_MAX) failed: %d\n", fpclassify (d));
246         result = 1;
247       }
248     d = nextafter (d, -INFINITY);
249     if (fpclassify (d) != FP_INFINITE)
250       {
251         printf ("fpclassify (-DBL_MAX-epsilon) failed: %d\n", fpclassify (d));
252         result = 1;
253       }
254   }
255 #ifndef NO_LONG_DOUBLE
256   {
257     long double ld;
258
259     ld = LDBL_MIN;
260     if (fpclassify (ld) != FP_NORMAL)
261       {
262         printf ("fpclassify (LDBL_MIN) failed: %d\n", fpclassify (ld));
263         result = 1;
264       }
265     ld = nextafterl (ld, LDBL_MIN / 2.0);
266     if (fpclassify (ld) != FP_SUBNORMAL)
267       {
268         printf ("fpclassify (LDBL_MIN-epsilon) failed: %d (%La)\n",
269                 fpclassify (ld), ld);
270         result = 1;
271       }
272     ld = nextafterl (ld, LDBL_MIN);
273     if (fpclassify (ld) != FP_NORMAL)
274       {
275         printf ("fpclassify (LDBL_MIN-epsilon+epsilon) failed: %d (%La)\n",
276                 fpclassify (ld), ld);
277         result = 1;
278       }
279
280     ld = -LDBL_MIN;
281     if (fpclassify (ld) != FP_NORMAL)
282       {
283         printf ("fpclassify (-LDBL_MIN) failed: %d\n", fpclassify (ld));
284         result = 1;
285       }
286     ld = nextafterl (ld, -LDBL_MIN / 2.0);
287     if (fpclassify (ld) != FP_SUBNORMAL)
288       {
289         printf ("fpclassify (-LDBL_MIN-epsilon) failed: %d (%La)\n",
290                 fpclassify (ld), ld);
291         result = 1;
292       }
293     ld = nextafterl (ld, -LDBL_MIN);
294     if (fpclassify (ld) != FP_NORMAL)
295       {
296         printf ("fpclassify (-LDBL_MIN-epsilon+epsilon) failed: %d (%La)\n",
297                 fpclassify (ld), ld);
298         result = 1;
299       }
300
301     ld = LDBL_MAX;
302     if (fpclassify (ld) != FP_NORMAL)
303       {
304         printf ("fpclassify (LDBL_MAX) failed: %d\n", fpclassify (ld));
305         result = 1;
306       }
307     ld = nextafterl (ld, INFINITY);
308     if (fpclassify (ld) != FP_INFINITE)
309       {
310         printf ("fpclassify (LDBL_MAX+epsilon) failed: %d\n", fpclassify (ld));
311         result = 1;
312       }
313
314     ld = -LDBL_MAX;
315     if (fpclassify (ld) != FP_NORMAL)
316       {
317         printf ("fpclassify (-LDBL_MAX) failed: %d\n", fpclassify (ld));
318         result = 1;
319       }
320     ld = nextafterl (ld, -INFINITY);
321     if (fpclassify (ld) != FP_INFINITE)
322       {
323         printf ("fpclassify (-LDBL_MAX-epsilon) failed: %d\n",
324                 fpclassify (ld));
325         result = 1;
326       }
327   }
328 #endif
329
330   if (! isnormal (FLT_MIN))
331     {
332       puts ("isnormal (FLT_MIN) failed");
333       result = 1;
334     }
335   if (! isnormal (DBL_MIN))
336     {
337       puts ("isnormal (DBL_MIN) failed");
338       result = 1;
339     }
340 #ifndef NO_LONG_DOUBLE
341   if (! isnormal (LDBL_MIN))
342     {
343       puts ("isnormal (LDBL_MIN) failed");
344       result = 1;
345     }
346 #endif
347
348 #ifdef __i386__
349   /* This is a test for the strange long doubles in x86 FPUs.  */
350   {
351     union
352     {
353       char b[10];
354       long double d;
355     } u =
356       { .b = { 0, 0, 0, 0, 0, 0, 0, 0x80, 0, 0 } };
357
358     if (fpclassify (u.d) != FP_NORMAL)
359       {
360         printf ("fpclassify (0x00008000000000000000) failed: %d (%Lg)\n",
361                 fpclassify (u.d), u.d);
362         result = 1;
363       }
364   }
365
366   /* Special NaNs in x86 long double.  Test for scalbl.  */
367   {
368     union
369     {
370       char b[10];
371       long double d;
372     } u =
373       { .b = { 0, 1, 0, 0, 0, 0, 0, 0xc0, 0xff, 0x7f } };
374     long double r;
375
376     r = scalbl (u.d, 0.0);
377     if (!isnan (r))
378       {
379         puts ("scalbl(NaN, 0) does not return NaN");
380         result = 1;
381       }
382     else if (memcmp (&r, &u.d, sizeof (double)) != 0)
383       {
384         puts ("scalbl(NaN, 0) does not return the same NaN");
385         result = 1;
386       }
387   }
388 #endif
389
390 #ifndef NO_LONG_DOUBLE
391   {
392     long double r;
393
394     feclearexcept (FE_ALL_EXCEPT);
395     r = scalbl (LDBL_MIN, 2147483647);
396     if (! isinf (r))
397       {
398         puts ("scalbl (LDBL_MIN, 2147483647) does not return Inf");
399         result = 1;
400       }
401     else if (signbit (r) != 0)
402       {
403         puts ("scalbl (LDBL_MIN, 2147483647) returns -Inf");
404         result = 1;
405       }
406     else if (fetestexcept (FE_UNDERFLOW))
407       {
408         puts ("scalbl(NaN, 0) raises underflow exception");
409         result = 1;
410       }
411
412     feclearexcept (FE_ALL_EXCEPT);
413     r = scalbl (LDBL_MAX, -2147483647);
414     if (r != 0.0)
415       {
416         puts ("scalbl (LDBL_MAX, -2147483647) does not return 0");
417         result = 1;
418       }
419     else if (signbit (r) != 0)
420       {
421         puts ("scalbl (LDBL_MAX, -2147483647) returns -Inf");
422         result = 1;
423       }
424     else if (fetestexcept (FE_OVERFLOW))
425       {
426         puts ("scalbl(NaN, 0) raises overflow exception");
427         result = 1;
428       }
429   }
430 #endif
431
432   return result;
433 }