Better ASSERT macro.
[gnulib.git] / tests / test-frexpl.c
1 /* Test of splitting a 'long double' into fraction and mantissa.
2    Copyright (C) 2007 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 2, or (at your option)
7    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, write to the Free Software Foundation,
16    Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
17
18 /* Written by Bruno Haible <bruno@clisp.org>, 2007.  */
19
20 #include <config.h>
21
22 #include <math.h>
23
24 #include <float.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27
28 #include "fpucw.h"
29 #include "isnanl-nolibm.h"
30
31 #define ASSERT(expr) \
32   do                                                                         \
33     {                                                                        \
34       if (!(expr))                                                           \
35         {                                                                    \
36           fprintf (stderr, "%s:%d: assertion failed\n", __FILE__, __LINE__); \
37           abort ();                                                          \
38         }                                                                    \
39     }                                                                        \
40   while (0)
41
42 /* On MIPS IRIX machines, LDBL_MIN_EXP is -1021, but the smallest reliable
43    exponent for 'long double' is -964.  For exponents below that, the
44    precision may be truncated to the precision used for 'double'.  */
45 #ifdef __sgi
46 # define MIN_NORMAL_EXP (LDBL_MIN_EXP + 57)
47 #else
48 # define MIN_NORMAL_EXP LDBL_MIN_EXP
49 #endif
50
51 static long double
52 my_ldexp (long double x, int d)
53 {
54   for (; d > 0; d--)
55     x *= 2.0L;
56   for (; d < 0; d++)
57     x *= 0.5L;
58   return x;
59 }
60
61 int
62 main ()
63 {
64   int i;
65   long double x;
66   DECL_LONG_DOUBLE_ROUNDING
67
68   BEGIN_LONG_DOUBLE_ROUNDING ();
69
70   { /* NaN.  */
71     int exp = -9999;
72     long double mantissa;
73     x = 0.0L / 0.0L;
74     mantissa = frexpl (x, &exp);
75     ASSERT (isnanl (mantissa));
76   }
77
78   { /* Positive infinity.  */
79     int exp = -9999;
80     long double mantissa;
81     x = 1.0L / 0.0L;
82     mantissa = frexpl (x, &exp);
83     ASSERT (mantissa == x);
84   }
85
86   { /* Negative infinity.  */
87     int exp = -9999;
88     long double mantissa;
89     x = -1.0L / 0.0L;
90     mantissa = frexpl (x, &exp);
91     ASSERT (mantissa == x);
92   }
93
94   { /* Positive zero.  */
95     int exp = -9999;
96     long double mantissa;
97     x = 0.0L;
98     mantissa = frexpl (x, &exp);
99     ASSERT (exp == 0);
100     ASSERT (mantissa == x);
101     ASSERT (!signbit (mantissa));
102   }
103
104   { /* Negative zero.  */
105     int exp = -9999;
106     long double mantissa;
107     x = -0.0L;
108     mantissa = frexpl (x, &exp);
109     ASSERT (exp == 0);
110     ASSERT (mantissa == x);
111     ASSERT (signbit (mantissa));
112   }
113
114   for (i = 1, x = 1.0L; i <= LDBL_MAX_EXP; i++, x *= 2.0L)
115     {
116       int exp = -9999;
117       long double mantissa = frexpl (x, &exp);
118       ASSERT (exp == i);
119       ASSERT (mantissa == 0.5L);
120     }
121   for (i = 1, x = 1.0L; i >= MIN_NORMAL_EXP; i--, x *= 0.5L)
122     {
123       int exp = -9999;
124       long double mantissa = frexpl (x, &exp);
125       ASSERT (exp == i);
126       ASSERT (mantissa == 0.5L);
127     }
128   for (; i >= LDBL_MIN_EXP - 100 && x > 0.0L; i--, x *= 0.5L)
129     {
130       int exp = -9999;
131       long double mantissa = frexpl (x, &exp);
132       ASSERT (exp == i);
133       ASSERT (mantissa == 0.5L);
134     }
135
136   for (i = 1, x = -1.0L; i <= LDBL_MAX_EXP; i++, x *= 2.0L)
137     {
138       int exp = -9999;
139       long double mantissa = frexpl (x, &exp);
140       ASSERT (exp == i);
141       ASSERT (mantissa == -0.5L);
142     }
143   for (i = 1, x = -1.0L; i >= MIN_NORMAL_EXP; i--, x *= 0.5L)
144     {
145       int exp = -9999;
146       long double mantissa = frexpl (x, &exp);
147       ASSERT (exp == i);
148       ASSERT (mantissa == -0.5L);
149     }
150   for (; i >= LDBL_MIN_EXP - 100 && x < 0.0L; i--, x *= 0.5L)
151     {
152       int exp = -9999;
153       long double mantissa = frexpl (x, &exp);
154       ASSERT (exp == i);
155       ASSERT (mantissa == -0.5L);
156     }
157
158   for (i = 1, x = 1.01L; i <= LDBL_MAX_EXP; i++, x *= 2.0L)
159     {
160       int exp = -9999;
161       long double mantissa = frexpl (x, &exp);
162       ASSERT (exp == i);
163       ASSERT (mantissa == 0.505L);
164     }
165   for (i = 1, x = 1.01L; i >= MIN_NORMAL_EXP; i--, x *= 0.5L)
166     {
167       int exp = -9999;
168       long double mantissa = frexpl (x, &exp);
169       ASSERT (exp == i);
170       ASSERT (mantissa == 0.505L);
171     }
172   for (; i >= LDBL_MIN_EXP - 100 && x > 0.0L; i--, x *= 0.5L)
173     {
174       int exp = -9999;
175       long double mantissa = frexpl (x, &exp);
176       ASSERT (exp == i);
177       ASSERT (mantissa >= 0.5L);
178       ASSERT (mantissa < 1.0L);
179       ASSERT (mantissa == my_ldexp (x, - exp));
180     }
181
182   for (i = 1, x = 1.73205L; i <= LDBL_MAX_EXP; i++, x *= 2.0L)
183     {
184       int exp = -9999;
185       long double mantissa = frexpl (x, &exp);
186       ASSERT (exp == i);
187       ASSERT (mantissa == 0.866025L);
188     }
189   for (i = 1, x = 1.73205L; i >= MIN_NORMAL_EXP; i--, x *= 0.5L)
190     {
191       int exp = -9999;
192       long double mantissa = frexpl (x, &exp);
193       ASSERT (exp == i);
194       ASSERT (mantissa == 0.866025L);
195     }
196   for (; i >= LDBL_MIN_EXP - 100 && x > 0.0L; i--, x *= 0.5L)
197     {
198       int exp = -9999;
199       long double mantissa = frexpl (x, &exp);
200       ASSERT (exp == i || exp == i + 1);
201       ASSERT (mantissa >= 0.5L);
202       ASSERT (mantissa < 1.0L);
203       ASSERT (mantissa == my_ldexp (x, - exp));
204     }
205
206   return 0;
207 }