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