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