ccb547b037b8dfbab3aad1f9717c3e98429d31d0
[platform/upstream/m4.git] / tests / test-frexpl.c
1 /* Test of splitting a 'long 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 (frexpl, long double, (long double, int *));
25
26 #include <float.h>
27
28 #include "fpucw.h"
29 #include "isnanl-nolibm.h"
30 #include "minus-zero.h"
31 #include "nan.h"
32 #include "macros.h"
33
34 /* Avoid some warnings from "gcc -Wshadow".
35    This file doesn't use the exp() function.  */
36 #undef exp
37 #define exp exponent
38
39 /* On MIPS IRIX machines, LDBL_MIN_EXP is -1021, but the smallest reliable
40    exponent for 'long double' is -964.  Similarly, on PowerPC machines,
41    LDBL_MIN_EXP is -1021, but the smallest reliable exponent for 'long double'
42    is -968.  For exponents below that, the precision may be truncated to the
43    precision used for 'double'.  */
44 #ifdef __sgi
45 # define MIN_NORMAL_EXP (LDBL_MIN_EXP + 57)
46 #elif defined __ppc || defined __ppc__ || defined __powerpc || defined __powerpc__
47 # define MIN_NORMAL_EXP (LDBL_MIN_EXP + 53)
48 #else
49 # define MIN_NORMAL_EXP LDBL_MIN_EXP
50 #endif
51
52 static long double
53 my_ldexp (long double x, int d)
54 {
55   for (; d > 0; d--)
56     x *= 2.0L;
57   for (; d < 0; d++)
58     x *= 0.5L;
59   return x;
60 }
61
62 int
63 main ()
64 {
65   int i;
66   long double x;
67   DECL_LONG_DOUBLE_ROUNDING
68
69   BEGIN_LONG_DOUBLE_ROUNDING ();
70
71   { /* NaN.  */
72     int exp = -9999;
73     long double mantissa;
74     x = NaNl ();
75     mantissa = frexpl (x, &exp);
76     ASSERT (isnanl (mantissa));
77   }
78
79   { /* Positive infinity.  */
80     int exp = -9999;
81     long double mantissa;
82     x = 1.0L / 0.0L;
83     mantissa = frexpl (x, &exp);
84     ASSERT (mantissa == x);
85   }
86
87   { /* Negative infinity.  */
88     int exp = -9999;
89     long double mantissa;
90     x = -1.0L / 0.0L;
91     mantissa = frexpl (x, &exp);
92     ASSERT (mantissa == x);
93   }
94
95   { /* Positive zero.  */
96     int exp = -9999;
97     long double mantissa;
98     x = 0.0L;
99     mantissa = frexpl (x, &exp);
100     ASSERT (exp == 0);
101     ASSERT (mantissa == x);
102     ASSERT (!signbit (mantissa));
103   }
104
105   { /* Negative zero.  */
106     int exp = -9999;
107     long double mantissa;
108     x = minus_zerol;
109     mantissa = frexpl (x, &exp);
110     ASSERT (exp == 0);
111     ASSERT (mantissa == x);
112     ASSERT (signbit (mantissa));
113   }
114
115   for (i = 1, x = 1.0L; i <= LDBL_MAX_EXP; i++, x *= 2.0L)
116     {
117       int exp = -9999;
118       long double mantissa = frexpl (x, &exp);
119       ASSERT (exp == i);
120       ASSERT (mantissa == 0.5L);
121     }
122   for (i = 1, x = 1.0L; i >= MIN_NORMAL_EXP; i--, x *= 0.5L)
123     {
124       int exp = -9999;
125       long double mantissa = frexpl (x, &exp);
126       ASSERT (exp == i);
127       ASSERT (mantissa == 0.5L);
128     }
129   for (; i >= LDBL_MIN_EXP - 100 && x > 0.0L; i--, x *= 0.5L)
130     {
131       int exp = -9999;
132       long double mantissa = frexpl (x, &exp);
133       ASSERT (exp == i);
134       ASSERT (mantissa == 0.5L);
135     }
136
137   for (i = 1, x = -1.0L; i <= LDBL_MAX_EXP; i++, x *= 2.0L)
138     {
139       int exp = -9999;
140       long double mantissa = frexpl (x, &exp);
141       ASSERT (exp == i);
142       ASSERT (mantissa == -0.5L);
143     }
144   for (i = 1, x = -1.0L; i >= MIN_NORMAL_EXP; i--, x *= 0.5L)
145     {
146       int exp = -9999;
147       long double mantissa = frexpl (x, &exp);
148       ASSERT (exp == i);
149       ASSERT (mantissa == -0.5L);
150     }
151   for (; i >= LDBL_MIN_EXP - 100 && x < 0.0L; i--, x *= 0.5L)
152     {
153       int exp = -9999;
154       long double mantissa = frexpl (x, &exp);
155       ASSERT (exp == i);
156       ASSERT (mantissa == -0.5L);
157     }
158
159   for (i = 1, x = 1.01L; i <= LDBL_MAX_EXP; i++, x *= 2.0L)
160     {
161       int exp = -9999;
162       long double mantissa = frexpl (x, &exp);
163       ASSERT (exp == i);
164       ASSERT (mantissa == 0.505L);
165     }
166   for (i = 1, x = 1.01L; i >= MIN_NORMAL_EXP; i--, x *= 0.5L)
167     {
168       int exp = -9999;
169       long double mantissa = frexpl (x, &exp);
170       ASSERT (exp == i);
171       ASSERT (mantissa == 0.505L);
172     }
173   for (; i >= LDBL_MIN_EXP - 100 && x > 0.0L; i--, x *= 0.5L)
174     {
175       int exp = -9999;
176       long double mantissa = frexpl (x, &exp);
177       ASSERT (exp == i);
178       ASSERT (mantissa >= 0.5L);
179       ASSERT (mantissa < 1.0L);
180       ASSERT (mantissa == my_ldexp (x, - exp));
181     }
182
183   for (i = 1, x = 1.73205L; i <= LDBL_MAX_EXP; i++, x *= 2.0L)
184     {
185       int exp = -9999;
186       long double mantissa = frexpl (x, &exp);
187       ASSERT (exp == i);
188       ASSERT (mantissa == 0.866025L);
189     }
190   for (i = 1, x = 1.73205L; i >= MIN_NORMAL_EXP; i--, x *= 0.5L)
191     {
192       int exp = -9999;
193       long double mantissa = frexpl (x, &exp);
194       ASSERT (exp == i);
195       ASSERT (mantissa == 0.866025L);
196     }
197   for (; i >= LDBL_MIN_EXP - 100 && x > 0.0L; i--, x *= 0.5L)
198     {
199       int exp = -9999;
200       long double mantissa = frexpl (x, &exp);
201       ASSERT (exp == i || exp == i + 1);
202       ASSERT (mantissa >= 0.5L);
203       ASSERT (mantissa < 1.0L);
204       ASSERT (mantissa == my_ldexp (x, - exp));
205     }
206
207   return 0;
208 }