1 /* Test file for mpfr_log_ui.
2
3 Copyright 2016-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 static void
compare_with_log(unsigned long n,mpfr_prec_t p)26 compare_with_log (unsigned long n, mpfr_prec_t p)
27 {
28 mpfr_t x, y;
29 int inex1, inex2;
30 mpfr_flags_t flags1;
31
32 mpfr_init2 (x, sizeof (unsigned long) * CHAR_BIT);
33 mpfr_init2 (y, p);
34 inex1 = mpfr_set_ui (x, n, MPFR_RNDN);
35 MPFR_ASSERTN(inex1 == 0);
36 inex1 = mpfr_log (y, x, MPFR_RNDN);
37 flags1 = __gmpfr_flags;
38 mpfr_set_prec (x, p);
39 inex2 = mpfr_log_ui (x, n, MPFR_RNDN);
40 MPFR_ASSERTN(inex1 == inex2);
41 MPFR_ASSERTN(flags1 == __gmpfr_flags);
42 MPFR_ASSERTN(mpfr_equal_p (x, y));
43 mpfr_clears (x, y, (mpfr_ptr) 0);
44 }
45
46 #define TEST_FUNCTION mpfr_log_ui
47 #define ONE_ARG
48 #define ULONG_ARG1
49 #define RAND_FUNCTION(x) mpfr_set_ui (x, randlimb (), MPFR_RNDN)
50 #include "tgeneric.c"
51
52 #define TEST_FUNCTION mpfr_log_ui
53
54 int
main(int argc,char * argv[])55 main (int argc, char *argv[])
56 {
57 unsigned int prec, yprec;
58 int rnd;
59 mpfr_t x, y, z, t, v;
60 unsigned long m, n;
61 int inex;
62 mpfr_exp_t emin, emax;
63 int i;
64
65 tests_start_mpfr ();
66
67 emin = mpfr_get_emin ();
68 emax = mpfr_get_emax ();
69
70 mpfr_inits2 (53, x, y, z, t, (mpfr_ptr) 0);
71 mpfr_init2 (v, sizeof (unsigned long) * CHAR_BIT);
72
73 if (argc >= 3) /* tlog_ui n prec [rnd] */
74 {
75 mpfr_set_prec (x, strtoul (argv[2], NULL, 10));
76 TEST_FUNCTION (x, strtoul (argv[1], NULL, 10),
77 argc > 3 ? (mpfr_rnd_t) atoi (argv[3]) : MPFR_RNDN);
78 mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN);
79 printf ("\n");
80 goto clear_and_exit;
81 }
82
83 mpfr_set_prec (x, 33);
84 mpfr_set_prec (y, 33);
85 mpfr_log_ui (x, 3, MPFR_RNDZ);
86 mpfr_set_str_binary (y, "1.0001100100111110101001111010101");
87 if (mpfr_cmp (x, y))
88 {
89 printf ("Error for log(3), prec=33, MPFR_RNDZ\n");
90 printf ("expected "); mpfr_dump (y);
91 printf ("got "); mpfr_dump (x);
92 exit (1);
93 }
94
95 mpfr_set_prec (x, 60);
96 mpfr_set_prec (y, 60);
97 mpfr_log_ui (x, 19, MPFR_RNDU);
98 mpfr_set_str_binary (y, "10.1111000111000110110000001100000010010110011001011000111010");
99 if (mpfr_cmp (x, y))
100 {
101 printf ("Error for log(19), prec=60, MPFR_RNDU\n");
102 printf ("expected "); mpfr_dump (y);
103 printf ("got "); mpfr_dump (x);
104 exit (1);
105 }
106
107 mpfr_clear_flags ();
108 inex = mpfr_log_ui (x, 0, MPFR_RNDN);
109 MPFR_ASSERTN (inex == 0);
110 MPFR_ASSERTN (mpfr_inf_p (x));
111 MPFR_ASSERTN (mpfr_sgn (x) < 0);
112 MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_DIVBY0);
113
114 mpfr_clear_flags ();
115 inex = mpfr_log_ui (x, 1, MPFR_RNDN);
116 MPFR_ASSERTN (inex == 0);
117 MPFR_ASSERTN (mpfr_zero_p (x));
118 MPFR_ASSERTN (mpfr_signbit (x) == 0);
119 MPFR_ASSERTN (__gmpfr_flags == 0);
120
121 for (prec = MPFR_PREC_MIN; prec <= 100; prec++)
122 {
123 mpfr_set_prec (x, prec);
124 mpfr_set_prec (z, prec);
125 mpfr_set_prec (t, prec);
126 yprec = prec + 20;
127 mpfr_set_prec (y, yprec);
128
129 for (m = 2; m < 130; m++)
130 RND_LOOP (rnd)
131 {
132 /* Start with n = 2 to 49 (mpfr_can_round would fail for n < 2),
133 then around ULONG_MAX/3, then around LONG_MAX, then
134 ULONG_MAX down to ULONG_MAX-19. */
135 n = (m < 50 ? m :
136 m < 80 ? ULONG_MAX/3 + m - 65 :
137 m < 110 ? (unsigned long) LONG_MAX + m - 95 :
138 ULONG_MAX - (m - 110));
139 inex = mpfr_set_ui (v, n, MPFR_RNDN);
140 MPFR_ASSERTN (inex == 0);
141 mpfr_log (y, v, MPFR_RNDN);
142 if (mpfr_can_round (y, yprec, MPFR_RNDN, MPFR_RNDZ, prec
143 + (rnd == MPFR_RNDN)))
144 {
145 mpfr_set (t, y, (mpfr_rnd_t) rnd);
146 for (i = 0; i <= 1; i++)
147 {
148 if (i)
149 {
150 mpfr_exp_t e;
151
152 if (MPFR_IS_SINGULAR (t))
153 break;
154 e = mpfr_get_exp (t);
155 set_emin (e);
156 set_emax (e);
157 }
158 TEST_FUNCTION (z, n, (mpfr_rnd_t) rnd);
159 if (i)
160 {
161 set_emin (emin);
162 set_emax (emax);
163 }
164 if (mpfr_cmp (t, z))
165 {
166 printf ("results differ for n = %lu, prec = %u,"
167 " %s%s\n", n, prec,
168 mpfr_print_rnd_mode ((mpfr_rnd_t) rnd),
169 i ? ", reduced exponent range" : "");
170 printf (" got ");
171 mpfr_dump (z);
172 printf (" expected ");
173 mpfr_dump (t);
174 printf (" approx ");
175 mpfr_dump (y);
176 exit (1);
177 }
178 }
179 }
180 else
181 {
182 /* We are not doing random tests. The precision increase
183 must have be chosen so that this case never occurs. */
184 printf ("mpfr_can_round failed for n = %lu, prec = %u, %s\n",
185 n, prec, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
186 exit (1);
187 }
188 }
189 }
190
191
192 test_generic (MPFR_PREC_MIN, 1000, 1);
193
194 for (n = 1; n < ULONG_MAX / 3; n *= 3)
195 compare_with_log (n, 10);
196
197 clear_and_exit:
198 mpfr_clears (x, y, z, t, v, (mpfr_ptr) 0);
199
200 tests_end_mpfr ();
201 return 0;
202 }
203