* lib/xalloc.h (DEFAULT_MXFAST): Track 64-bit glibc.
[gnulib.git] / tests / test-frexp.c
1 /* Test of splitting a double into fraction and mantissa.
2    Copyright (C) 2007-2011 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 <http://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 #include "signature.h"
24 SIGNATURE_CHECK (frexp, double, (double, int *));
25
26 #include <float.h>
27
28 #include "isnand-nolibm.h"
29 #include "minus-zero.h"
30 #include "nan.h"
31 #include "macros.h"
32
33 /* Avoid some warnings from "gcc -Wshadow".
34    This file doesn't use the exp() function.  */
35 #undef exp
36 #define exp exponent
37
38 static double
39 my_ldexp (double x, int d)
40 {
41   for (; d > 0; d--)
42     x *= 2.0;
43   for (; d < 0; d++)
44     x *= 0.5;
45   return x;
46 }
47
48 int
49 main ()
50 {
51   int i;
52   /* The use of 'volatile' guarantees that excess precision bits are dropped
53      when dealing with denormalized numbers.  It is necessary on x86 systems
54      where double-floats are not IEEE compliant by default, to avoid that the
55      results become platform and compiler option dependent.  'volatile' is a
56      portable alternative to gcc's -ffloat-store option.  */
57   volatile double x;
58
59   { /* NaN.  */
60     int exp = -9999;
61     double mantissa;
62     x = NaNd ();
63     mantissa = frexp (x, &exp);
64     ASSERT (isnand (mantissa));
65   }
66
67   { /* Positive infinity.  */
68     int exp = -9999;
69     double mantissa;
70     x = 1.0 / 0.0;
71     mantissa = frexp (x, &exp);
72     ASSERT (mantissa == x);
73   }
74
75   { /* Negative infinity.  */
76     int exp = -9999;
77     double mantissa;
78     x = -1.0 / 0.0;
79     mantissa = frexp (x, &exp);
80     ASSERT (mantissa == x);
81   }
82
83   { /* Positive zero.  */
84     int exp = -9999;
85     double mantissa;
86     x = 0.0;
87     mantissa = frexp (x, &exp);
88     ASSERT (exp == 0);
89     ASSERT (mantissa == x);
90     ASSERT (!signbit (mantissa));
91   }
92
93   { /* Negative zero.  */
94     int exp = -9999;
95     double mantissa;
96     x = minus_zerod;
97     mantissa = frexp (x, &exp);
98     ASSERT (exp == 0);
99     ASSERT (mantissa == x);
100     ASSERT (signbit (mantissa));
101   }
102
103   for (i = 1, x = 1.0; i <= DBL_MAX_EXP; i++, x *= 2.0)
104     {
105       int exp = -9999;
106       double mantissa = frexp (x, &exp);
107       ASSERT (exp == i);
108       ASSERT (mantissa == 0.5);
109     }
110   for (i = 1, x = 1.0; i >= DBL_MIN_EXP; i--, x *= 0.5)
111     {
112       int exp = -9999;
113       double mantissa = frexp (x, &exp);
114       ASSERT (exp == i);
115       ASSERT (mantissa == 0.5);
116     }
117   for (; i >= DBL_MIN_EXP - 100 && x > 0.0; i--, x *= 0.5)
118     {
119       int exp = -9999;
120       double mantissa = frexp (x, &exp);
121       ASSERT (exp == i);
122       ASSERT (mantissa == 0.5);
123     }
124
125   for (i = 1, x = -1.0; i <= DBL_MAX_EXP; i++, x *= 2.0)
126     {
127       int exp = -9999;
128       double mantissa = frexp (x, &exp);
129       ASSERT (exp == i);
130       ASSERT (mantissa == -0.5);
131     }
132   for (i = 1, x = -1.0; i >= DBL_MIN_EXP; i--, x *= 0.5)
133     {
134       int exp = -9999;
135       double mantissa = frexp (x, &exp);
136       ASSERT (exp == i);
137       ASSERT (mantissa == -0.5);
138     }
139   for (; i >= DBL_MIN_EXP - 100 && x < 0.0; i--, x *= 0.5)
140     {
141       int exp = -9999;
142       double mantissa = frexp (x, &exp);
143       ASSERT (exp == i);
144       ASSERT (mantissa == -0.5);
145     }
146
147   for (i = 1, x = 1.01; i <= DBL_MAX_EXP; i++, x *= 2.0)
148     {
149       int exp = -9999;
150       double mantissa = frexp (x, &exp);
151       ASSERT (exp == i);
152       ASSERT (mantissa == 0.505);
153     }
154   for (i = 1, x = 1.01; i >= DBL_MIN_EXP; i--, x *= 0.5)
155     {
156       int exp = -9999;
157       double mantissa = frexp (x, &exp);
158       ASSERT (exp == i);
159       ASSERT (mantissa == 0.505);
160     }
161   for (; i >= DBL_MIN_EXP - 100 && x > 0.0; i--, x *= 0.5)
162     {
163       int exp = -9999;
164       double mantissa = frexp (x, &exp);
165       ASSERT (exp == i);
166       ASSERT (mantissa >= 0.5);
167       ASSERT (mantissa < 1.0);
168       ASSERT (mantissa == my_ldexp (x, - exp));
169     }
170
171   for (i = 1, x = 1.73205; i <= DBL_MAX_EXP; i++, x *= 2.0)
172     {
173       int exp = -9999;
174       double mantissa = frexp (x, &exp);
175       ASSERT (exp == i);
176       ASSERT (mantissa == 0.866025);
177     }
178   for (i = 1, x = 1.73205; i >= DBL_MIN_EXP; i--, x *= 0.5)
179     {
180       int exp = -9999;
181       double mantissa = frexp (x, &exp);
182       ASSERT (exp == i);
183       ASSERT (mantissa == 0.866025);
184     }
185   for (; i >= DBL_MIN_EXP - 100 && x > 0.0; i--, x *= 0.5)
186     {
187       int exp = -9999;
188       double mantissa = frexp (x, &exp);
189       ASSERT (exp == i || exp == i + 1);
190       ASSERT (mantissa >= 0.5);
191       ASSERT (mantissa < 1.0);
192       ASSERT (mantissa == my_ldexp (x, - exp));
193     }
194
195   return 0;
196 }