New module 'fpucw'.
[pspp] / 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 <stdlib.h>
26
27 #include "fpucw.h"
28
29 #define ASSERT(expr) if (!(expr)) abort ();
30
31 static long double
32 my_ldexp (long double x, int d)
33 {
34   for (; d > 0; d--)
35     x *= 2.0L;
36   for (; d < 0; d++)
37     x *= 0.5L;
38   return x;
39 }
40
41 int
42 main ()
43 {
44   int i;
45   long double x;
46   DECL_LONG_DOUBLE_ROUNDING
47
48   BEGIN_LONG_DOUBLE_ROUNDING ();
49
50   { /* NaN.  */
51     int exp = -9999;
52     long double mantissa;
53     x = 0.0L / 0.0L;
54     mantissa = frexpl (x, &exp);
55     ASSERT (mantissa != mantissa);
56   }
57
58   { /* Positive infinity.  */
59     int exp = -9999;
60     long double mantissa;
61     x = 1.0L / 0.0L;
62     mantissa = frexpl (x, &exp);
63     ASSERT (mantissa == x);
64   }
65
66   { /* Negative infinity.  */
67     int exp = -9999;
68     long double mantissa;
69     x = -1.0L / 0.0L;
70     mantissa = frexpl (x, &exp);
71     ASSERT (mantissa == x);
72   }
73
74   { /* Positive zero.  */
75     int exp = -9999;
76     long double mantissa;
77     x = 0.0L;
78     mantissa = frexpl (x, &exp);
79     ASSERT (exp == 0);
80     ASSERT (mantissa == x);
81   }
82
83   { /* Negative zero.  */
84     int exp = -9999;
85     long double mantissa;
86     x = -0.0L;
87     mantissa = frexpl (x, &exp);
88     ASSERT (exp == 0);
89     ASSERT (mantissa == x);
90   }
91
92   for (i = 1, x = 1.0L; i <= LDBL_MAX_EXP; i++, x *= 2.0L)
93     {
94       int exp = -9999;
95       long double mantissa = frexpl (x, &exp);
96       ASSERT (exp == i);
97       ASSERT (mantissa == 0.5L);
98     }
99   for (i = 1, x = 1.0L; i >= LDBL_MIN_EXP; i--, x *= 0.5L)
100     {
101       int exp = -9999;
102       long double mantissa = frexpl (x, &exp);
103       ASSERT (exp == i);
104       ASSERT (mantissa == 0.5L);
105     }
106   for (; i >= LDBL_MIN_EXP - 100 && x > 0.0L; i--, x *= 0.5L)
107     {
108       int exp = -9999;
109       long double mantissa = frexpl (x, &exp);
110       ASSERT (exp == i);
111       ASSERT (mantissa == 0.5L);
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 >= LDBL_MIN_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.01L; 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.505L);
142     }
143   for (i = 1, x = 1.01L; i >= LDBL_MIN_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.505L);
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       ASSERT (mantissa < 1.0L);
157       ASSERT (mantissa == my_ldexp (x, - exp));
158     }
159
160   for (i = 1, x = 1.73205L; i <= LDBL_MAX_EXP; i++, x *= 2.0L)
161     {
162       int exp = -9999;
163       long double mantissa = frexpl (x, &exp);
164       ASSERT (exp == i);
165       ASSERT (mantissa == 0.866025L);
166     }
167   for (i = 1, x = 1.73205L; i >= LDBL_MIN_EXP; i--, x *= 0.5L)
168     {
169       int exp = -9999;
170       long double mantissa = frexpl (x, &exp);
171       ASSERT (exp == i);
172       ASSERT (mantissa == 0.866025L);
173     }
174   for (; i >= LDBL_MIN_EXP - 100 && x > 0.0L; i--, x *= 0.5L)
175     {
176       int exp = -9999;
177       long double mantissa = frexpl (x, &exp);
178       ASSERT (exp == i || exp == i + 1);
179       ASSERT (mantissa >= 0.5L);
180       ASSERT (mantissa < 1.0L);
181       ASSERT (mantissa == my_ldexp (x, - exp));
182     }
183
184   return 0;
185 }