1 /* Test file for mpfr_exp2m1.
2
3 Copyright 2001-2023 Free Software Foundation, Inc.
4 Contributed by the AriC and Caramba projects, INRIA.
5
6 This file is part of the GNU MPFR Library.
7
8 The GNU MPFR Library is free software; you can redistribute it and/or modify
9 it under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or (at your
11 option) any later version.
12
13 The GNU MPFR Library is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
16 License for more details.
17
18 You should have received a copy of the GNU Lesser General Public License
19 along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
20 https://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
21 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
22
23 #include "mpfr-test.h"
24
25 #define TEST_FUNCTION mpfr_exp2m1
26 #define TEST_RANDOM_EMIN -36
27 #define TEST_RANDOM_EMAX 36
28 #include "tgeneric.c"
29
30 static void
special(void)31 special (void)
32 {
33 mpfr_t x, y;
34 int i;
35
36 mpfr_init2 (x, 2);
37 mpfr_init2 (y, 2);
38
39 mpfr_set_nan (x);
40 mpfr_exp2m1 (y, x, MPFR_RNDN);
41 if (!mpfr_nan_p (y))
42 {
43 printf ("Error for exp2m1(NaN)\n");
44 exit (1);
45 }
46
47 mpfr_set_inf (x, 1);
48 mpfr_exp2m1 (y, x, MPFR_RNDN);
49 if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0)
50 {
51 printf ("Error for exp2m1(+Inf)\n");
52 exit (1);
53 }
54
55 mpfr_set_inf (x, -1);
56 mpfr_exp2m1 (y, x, MPFR_RNDN);
57 if (mpfr_cmp_si (y, -1) != 0)
58 {
59 printf ("Error for exp2m1(-Inf)\n");
60 exit (1);
61 }
62
63 mpfr_set_ui (x, 0, MPFR_RNDN);
64 mpfr_exp2m1 (y, x, MPFR_RNDN);
65 if (MPFR_NOTZERO (y) || MPFR_IS_NEG (y))
66 {
67 printf ("Error for exp2m1(+0)\n");
68 exit (1);
69 }
70
71 mpfr_neg (x, x, MPFR_RNDN);
72 mpfr_exp2m1 (y, x, MPFR_RNDN);
73 if (MPFR_NOTZERO (y) || MPFR_IS_POS (y))
74 {
75 printf ("Error for exp2m1(-0)\n");
76 exit (1);
77 }
78
79 /* Check overflow of exp2m1(x) */
80 mpfr_clear_flags ();
81 mpfr_set_str_binary (x, "1.1E1000000000");
82 i = mpfr_exp2m1 (x, x, MPFR_RNDN);
83 MPFR_ASSERTN (MPFR_IS_INF (x) && MPFR_IS_POS (x));
84 MPFR_ASSERTN (mpfr_overflow_p ());
85 MPFR_ASSERTN (i > 0);
86
87 mpfr_clear_flags ();
88 mpfr_set_str_binary (x, "1.1E1000000000");
89 i = mpfr_exp2m1 (x, x, MPFR_RNDU);
90 MPFR_ASSERTN (MPFR_IS_INF (x) && MPFR_IS_POS (x));
91 MPFR_ASSERTN (mpfr_overflow_p ());
92 MPFR_ASSERTN (i > 0);
93
94 mpfr_clear_flags ();
95 mpfr_set_str_binary (x, "1.1E1000000000");
96 i = mpfr_exp2m1 (x, x, MPFR_RNDD);
97 MPFR_ASSERTN (!MPFR_IS_INF (x) && MPFR_IS_POS (x));
98 MPFR_ASSERTN (mpfr_overflow_p ());
99 MPFR_ASSERTN (i < 0);
100
101 /* Check internal underflow of exp2m1 (x) */
102 mpfr_set_prec (x, 2);
103 mpfr_clear_flags ();
104 mpfr_set_str_binary (x, "-1.1E1000000000");
105 i = mpfr_exp2m1 (x, x, MPFR_RNDN);
106 MPFR_ASSERTN (mpfr_cmp_si (x, -1) == 0);
107 MPFR_ASSERTN (!mpfr_overflow_p () && !mpfr_underflow_p ());
108 MPFR_ASSERTN (i < 0);
109
110 mpfr_set_str_binary (x, "-1.1E1000000000");
111 i = mpfr_exp2m1 (x, x, MPFR_RNDD);
112 MPFR_ASSERTN (mpfr_cmp_si (x, -1) == 0);
113 MPFR_ASSERTN (!mpfr_overflow_p () && !mpfr_underflow_p ());
114 MPFR_ASSERTN (i < 0);
115
116 mpfr_set_str_binary (x, "-1.1E1000000000");
117 i = mpfr_exp2m1 (x, x, MPFR_RNDZ);
118 MPFR_ASSERTN (mpfr_cmp_str (x, "-0.11", 2, MPFR_RNDN) == 0);
119 MPFR_ASSERTN (!mpfr_overflow_p () && !mpfr_underflow_p ());
120 MPFR_ASSERTN (i > 0);
121
122 mpfr_set_str_binary (x, "-1.1E1000000000");
123 i = mpfr_exp2m1 (x, x, MPFR_RNDU);
124 MPFR_ASSERTN (mpfr_cmp_str (x, "-0.11", 2, MPFR_RNDN) == 0);
125 MPFR_ASSERTN (!mpfr_overflow_p () && !mpfr_underflow_p ());
126 MPFR_ASSERTN (i > 0);
127
128 /* hard-coded test */
129 mpfr_set_prec (x, 32);
130 mpfr_set_prec (y, 32);
131 mpfr_set_ui_2exp (x, 1686629713UL, -29, MPFR_RNDN); /* approximates Pi */
132 i = mpfr_exp2m1 (y, x, MPFR_RNDN);
133 MPFR_ASSERTN (mpfr_cmp_ui_2exp (y, 2100501491UL, -28) == 0);
134 MPFR_ASSERTN (i < 0);
135
136 mpfr_clear (x);
137 mpfr_clear (y);
138 }
139
140 /* test integer x, -100 <= x <= 100, where 2^x-1 is exact */
141 static void
test_exact(void)142 test_exact (void)
143 {
144 long k;
145 mpfr_t x, y, z;
146 mpz_t n;
147 mpfr_prec_t p;
148 int i, j, r;
149
150 mpfr_init2 (x, 7); /* 100 is exact within 7 bits */
151 mpfr_init2 (y, MPFR_PREC_MIN);
152 mpfr_init2 (z, MPFR_PREC_MIN);
153 mpz_init_set_ui (n, 1);
154 for (k = 1; k <= 100; k++)
155 {
156 /* invariant: n = 2^k-1 */
157 for (p = MPFR_PREC_MIN; p <= 100; p++)
158 {
159 mpfr_set_prec (y, p);
160 mpfr_set_prec (z, p);
161 mpfr_set_si (x, k, MPFR_RNDN);
162 /* for RNDF, result may differ */
163 RND_LOOP_NO_RNDF(r)
164 {
165 i = mpfr_exp2m1 (y, x, (mpfr_rnd_t) r);
166 j = mpfr_set_z (z, n, (mpfr_rnd_t) r);
167 if (!mpfr_equal_p (y, z))
168 {
169 printf ("Error for mpfr_exp2m1, x=%ld, rnd=%s\n", k,
170 mpfr_print_rnd_mode ((mpfr_rnd_t) r));
171 printf ("expected "); mpfr_dump (z);
172 printf ("got "); mpfr_dump (y);
173 exit (1);
174 }
175 if ((i == 0 && j != 0) || (i != 0 && j == 0) || (i * j < 0))
176 {
177 printf ("Bar ternary value for mpfr_exp2m1, x=%ld, rnd=%s\n",
178 k, mpfr_print_rnd_mode ((mpfr_rnd_t) r));
179 printf ("expected %d\n", j);
180 printf ("got %d\n", i);
181 exit (1);
182 }
183 }
184 mpfr_set_si (x, -k, MPFR_RNDN);
185 /* 1/2^k-1 = (1-2^k)/2^k = -n/2^k */
186 RND_LOOP_NO_RNDF(r)
187 {
188 i = mpfr_exp2m1 (y, x, (mpfr_rnd_t) r);
189 j = mpfr_set_z (z, n, MPFR_INVERT_RND((mpfr_rnd_t) r));
190 mpfr_neg (z, z, (mpfr_rnd_t) r);
191 j = -j;
192 mpfr_div_2ui (z, z, k, (mpfr_rnd_t) r);
193 if (!mpfr_equal_p (y, z))
194 {
195 printf ("Error for mpfr_exp2m1, x=%ld, rnd=%s\n", -k,
196 mpfr_print_rnd_mode ((mpfr_rnd_t) r));
197 printf ("expected "); mpfr_dump (z);
198 printf ("got "); mpfr_dump (y);
199 exit (1);
200 }
201 if ((i == 0 && j != 0) || (i != 0 && j == 0) || (i * j < 0))
202 {
203 printf ("Bar ternary value for mpfr_exp2m1, x=%ld, rnd=%s\n",
204 -k, mpfr_print_rnd_mode ((mpfr_rnd_t) r));
205 printf ("expected %d\n", j);
206 printf ("got %d\n", i);
207 exit (1);
208 }
209 }
210 }
211 mpz_mul_2exp (n, n, 1);
212 mpz_add_ui (n, n, 1);
213 }
214 mpfr_clear (x);
215 mpfr_clear (y);
216 mpfr_clear (z);
217 mpz_clear (n);
218 }
219
220 int
main(int argc,char * argv[])221 main (int argc, char *argv[])
222 {
223 tests_start_mpfr ();
224
225 special ();
226
227 test_exact ();
228
229 test_generic (MPFR_PREC_MIN, 100, 100);
230
231 tests_end_mpfr ();
232 return 0;
233 }
234