tset_si.c revision 1.1.1.5 1 1.1.1.4 mrg /* Test file for mpfr_set_si, mpfr_set_ui, mpfr_get_si and mpfr_get_ui.
2 1.1 mrg
3 1.1.1.5 mrg Copyright 1999, 2001-2020 Free Software Foundation, Inc.
4 1.1.1.3 mrg Contributed by the AriC and Caramba projects, INRIA.
5 1.1 mrg
6 1.1 mrg This file is part of the GNU MPFR Library.
7 1.1 mrg
8 1.1 mrg The GNU MPFR Library is free software; you can redistribute it and/or modify
9 1.1 mrg it under the terms of the GNU Lesser General Public License as published by
10 1.1 mrg the Free Software Foundation; either version 3 of the License, or (at your
11 1.1 mrg option) any later version.
12 1.1 mrg
13 1.1 mrg The GNU MPFR Library is distributed in the hope that it will be useful, but
14 1.1 mrg WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 1.1 mrg or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
16 1.1 mrg License for more details.
17 1.1 mrg
18 1.1 mrg You should have received a copy of the GNU Lesser General Public License
19 1.1 mrg along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
20 1.1.1.5 mrg https://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
21 1.1 mrg 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
22 1.1 mrg
23 1.1 mrg #include "mpfr-test.h"
24 1.1 mrg
25 1.1.1.4 mrg #define PRINT_ERROR(str) \
26 1.1.1.4 mrg do { printf ("Error for %s\n", str); exit (1); } while (0)
27 1.1 mrg
28 1.1 mrg static void
29 1.1 mrg test_2exp (void)
30 1.1 mrg {
31 1.1 mrg mpfr_t x;
32 1.1 mrg int res;
33 1.1 mrg
34 1.1 mrg mpfr_init2 (x, 32);
35 1.1 mrg
36 1.1 mrg mpfr_set_ui_2exp (x, 1, 0, MPFR_RNDN);
37 1.1.1.4 mrg if (mpfr_cmp_ui (x, 1) != 0)
38 1.1.1.4 mrg PRINT_ERROR ("(1U,0)");
39 1.1 mrg
40 1.1 mrg mpfr_set_ui_2exp (x, 1024, -10, MPFR_RNDN);
41 1.1.1.4 mrg if (mpfr_cmp_ui(x, 1) != 0)
42 1.1.1.4 mrg PRINT_ERROR ("(1024U,-10)");
43 1.1 mrg
44 1.1 mrg mpfr_set_ui_2exp (x, 1024, 10, MPFR_RNDN);
45 1.1.1.4 mrg if (mpfr_cmp_ui (x, 1024 * 1024) != 0)
46 1.1.1.4 mrg PRINT_ERROR ("(1024U,+10)");
47 1.1 mrg
48 1.1 mrg mpfr_set_si_2exp (x, -1024L * 1024L, -10, MPFR_RNDN);
49 1.1.1.4 mrg if (mpfr_cmp_si (x, -1024) != 0)
50 1.1.1.4 mrg PRINT_ERROR ("(1M,-10)");
51 1.1 mrg
52 1.1 mrg mpfr_set_ui_2exp (x, 0x92345678, 16, MPFR_RNDN);
53 1.1.1.4 mrg if (mpfr_cmp_str (x, "92345678@4", 16, MPFR_RNDN) != 0)
54 1.1.1.4 mrg PRINT_ERROR ("(x92345678U,+16)");
55 1.1 mrg
56 1.1 mrg mpfr_set_si_2exp (x, -0x1ABCDEF0, -256, MPFR_RNDN);
57 1.1.1.4 mrg if (mpfr_cmp_str (x, "-1ABCDEF0@-64", 16, MPFR_RNDN) != 0)
58 1.1.1.4 mrg PRINT_ERROR ("(-x1ABCDEF0,-256)");
59 1.1 mrg
60 1.1 mrg mpfr_set_prec (x, 2);
61 1.1 mrg res = mpfr_set_si_2exp (x, 7, 10, MPFR_RNDU);
62 1.1.1.4 mrg if (mpfr_cmp_ui (x, 1<<13) != 0 || res <= 0)
63 1.1.1.4 mrg PRINT_ERROR ("Prec 2 + si_2exp");
64 1.1 mrg
65 1.1 mrg res = mpfr_set_ui_2exp (x, 7, 10, MPFR_RNDU);
66 1.1.1.4 mrg if (mpfr_cmp_ui (x, 1<<13) != 0 || res <= 0)
67 1.1.1.4 mrg PRINT_ERROR ("Prec 2 + ui_2exp");
68 1.1 mrg
69 1.1 mrg mpfr_clear_flags ();
70 1.1 mrg mpfr_set_ui_2exp (x, 17, MPFR_EMAX_MAX, MPFR_RNDN);
71 1.1 mrg if (!mpfr_inf_p (x) || MPFR_IS_NEG (x))
72 1.1.1.4 mrg PRINT_ERROR ("mpfr_set_ui_2exp and overflow (bad result)");
73 1.1 mrg if (!mpfr_overflow_p ())
74 1.1.1.4 mrg PRINT_ERROR ("mpfr_set_ui_2exp and overflow (overflow flag not set)");
75 1.1 mrg
76 1.1 mrg mpfr_clear_flags ();
77 1.1 mrg mpfr_set_si_2exp (x, 17, MPFR_EMAX_MAX, MPFR_RNDN);
78 1.1 mrg if (!mpfr_inf_p (x) || MPFR_IS_NEG (x))
79 1.1.1.4 mrg PRINT_ERROR ("mpfr_set_si_2exp (pos) and overflow (bad result)");
80 1.1 mrg if (!mpfr_overflow_p ())
81 1.1.1.4 mrg PRINT_ERROR ("mpfr_set_si_2exp (pos) and overflow (overflow flag not set)");
82 1.1 mrg
83 1.1 mrg mpfr_clear_flags ();
84 1.1 mrg mpfr_set_si_2exp (x, -17, MPFR_EMAX_MAX, MPFR_RNDN);
85 1.1 mrg if (!mpfr_inf_p (x) || MPFR_IS_POS (x))
86 1.1.1.4 mrg PRINT_ERROR ("mpfr_set_si_2exp (neg) and overflow (bad result)");
87 1.1 mrg if (!mpfr_overflow_p ())
88 1.1.1.4 mrg PRINT_ERROR ("mpfr_set_si_2exp (neg) and overflow (overflow flag not set)");
89 1.1 mrg
90 1.1 mrg mpfr_clear (x);
91 1.1 mrg }
92 1.1 mrg
93 1.1.1.5 mrg #define REXP 1024
94 1.1.1.5 mrg
95 1.1.1.5 mrg static void
96 1.1.1.5 mrg test_2exp_extreme_aux (void)
97 1.1.1.5 mrg {
98 1.1.1.5 mrg mpfr_t x1, x2, y;
99 1.1.1.5 mrg mpfr_exp_t e, ep[1 + 8 * 5], eb[] =
100 1.1.1.5 mrg { MPFR_EMIN_MIN, -REXP, REXP, MPFR_EMAX_MAX, MPFR_EXP_MAX };
101 1.1.1.5 mrg mpfr_flags_t flags1, flags2;
102 1.1.1.5 mrg int i, j, rnd, inex1, inex2;
103 1.1.1.5 mrg char s;
104 1.1.1.5 mrg
105 1.1.1.5 mrg ep[0] = MPFR_EXP_MIN;
106 1.1.1.5 mrg for (i = 0; i < numberof(eb); i++)
107 1.1.1.5 mrg for (j = 0; j < 8; j++)
108 1.1.1.5 mrg ep[1 + 8 * i + j] = eb[i] - j;
109 1.1.1.5 mrg
110 1.1.1.5 mrg mpfr_inits2 (3, x1, x2, (mpfr_ptr) 0);
111 1.1.1.5 mrg mpfr_init2 (y, 32);
112 1.1.1.5 mrg
113 1.1.1.5 mrg for (i = 0; i < numberof(ep); i++)
114 1.1.1.5 mrg for (j = -31; j <= 31; j++)
115 1.1.1.5 mrg RND_LOOP_NO_RNDF (rnd)
116 1.1.1.5 mrg {
117 1.1.1.5 mrg int sign = j < 0 ? -1 : 1;
118 1.1.1.5 mrg
119 1.1.1.5 mrg /* Compute the expected value, inex and flags */
120 1.1.1.5 mrg inex1 = mpfr_set_si (y, j, MPFR_RNDN);
121 1.1.1.5 mrg MPFR_ASSERTN (inex1 == 0);
122 1.1.1.5 mrg inex1 = mpfr_set (x1, y, (mpfr_rnd_t) rnd);
123 1.1.1.5 mrg /* x1 is the rounded value and inex1 the ternary value,
124 1.1.1.5 mrg assuming that the exponent argument is 0 (this is the
125 1.1.1.5 mrg rounded significand of the final result, assuming an
126 1.1.1.5 mrg unbounded exponent range). The multiplication by a
127 1.1.1.5 mrg power of 2 is exact, unless underflow/overflow occurs.
128 1.1.1.5 mrg The tests on the exponent below avoid integer overflows
129 1.1.1.5 mrg (ep[i] may take extreme values). */
130 1.1.1.5 mrg e = mpfr_get_exp (x1);
131 1.1.1.5 mrg mpfr_clear_flags ();
132 1.1.1.5 mrg if (j != 0 && ep[i] < __gmpfr_emin - e) /* underflow */
133 1.1.1.5 mrg {
134 1.1.1.5 mrg mpfr_rnd_t r =
135 1.1.1.5 mrg (rnd == MPFR_RNDN &&
136 1.1.1.5 mrg (ep[i] < __gmpfr_emin - mpfr_get_exp (y) - 1 ||
137 1.1.1.5 mrg IS_POW2 (sign * j))) ?
138 1.1.1.5 mrg MPFR_RNDZ : (mpfr_rnd_t) rnd;
139 1.1.1.5 mrg inex1 = mpfr_underflow (x1, r, sign);
140 1.1.1.5 mrg flags1 = __gmpfr_flags;
141 1.1.1.5 mrg }
142 1.1.1.5 mrg else if (j != 0 && ep[i] > __gmpfr_emax - e) /* overflow */
143 1.1.1.5 mrg {
144 1.1.1.5 mrg inex1 = mpfr_overflow (x1, (mpfr_rnd_t) rnd, sign);
145 1.1.1.5 mrg flags1 = __gmpfr_flags;
146 1.1.1.5 mrg }
147 1.1.1.5 mrg else
148 1.1.1.5 mrg {
149 1.1.1.5 mrg if (j != 0)
150 1.1.1.5 mrg mpfr_set_exp (x1, ep[i] + e);
151 1.1.1.5 mrg flags1 = inex1 != 0 ? MPFR_FLAGS_INEXACT : 0;
152 1.1.1.5 mrg }
153 1.1.1.5 mrg
154 1.1.1.5 mrg /* Test mpfr_set_si_2exp */
155 1.1.1.5 mrg mpfr_clear_flags ();
156 1.1.1.5 mrg inex2 = mpfr_set_si_2exp (x2, j, ep[i], (mpfr_rnd_t) rnd);
157 1.1.1.5 mrg flags2 = __gmpfr_flags;
158 1.1.1.5 mrg
159 1.1.1.5 mrg if (! (flags1 == flags2 && SAME_SIGN (inex1, inex2) &&
160 1.1.1.5 mrg mpfr_equal_p (x1, x2)))
161 1.1.1.5 mrg {
162 1.1.1.5 mrg s = 's';
163 1.1.1.5 mrg goto err_extreme;
164 1.1.1.5 mrg }
165 1.1.1.5 mrg
166 1.1.1.5 mrg if (j < 0)
167 1.1.1.5 mrg continue;
168 1.1.1.5 mrg
169 1.1.1.5 mrg /* Test mpfr_set_ui_2exp */
170 1.1.1.5 mrg mpfr_clear_flags ();
171 1.1.1.5 mrg inex2 = mpfr_set_ui_2exp (x2, j, ep[i], (mpfr_rnd_t) rnd);
172 1.1.1.5 mrg flags2 = __gmpfr_flags;
173 1.1.1.5 mrg
174 1.1.1.5 mrg if (! (flags1 == flags2 && SAME_SIGN (inex1, inex2) &&
175 1.1.1.5 mrg mpfr_equal_p (x1, x2)))
176 1.1.1.5 mrg {
177 1.1.1.5 mrg s = 'u';
178 1.1.1.5 mrg err_extreme:
179 1.1.1.5 mrg printf ("Error in extreme mpfr_set_%ci_2exp for i=%d j=%d %s\n",
180 1.1.1.5 mrg s, i, j, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
181 1.1.1.5 mrg printf ("emin=%" MPFR_EXP_FSPEC "d "
182 1.1.1.5 mrg "emax=%" MPFR_EXP_FSPEC "d\n",
183 1.1.1.5 mrg (mpfr_eexp_t) __gmpfr_emin,
184 1.1.1.5 mrg (mpfr_eexp_t) __gmpfr_emax);
185 1.1.1.5 mrg printf ("ep[%d] = %" MPFR_EXP_FSPEC "d\n",
186 1.1.1.5 mrg i, (mpfr_eexp_t) ep[i]);
187 1.1.1.5 mrg printf ("Expected ");
188 1.1.1.5 mrg mpfr_dump (x1);
189 1.1.1.5 mrg printf ("with inex = %d and flags =", inex1);
190 1.1.1.5 mrg flags_out (flags1);
191 1.1.1.5 mrg printf ("Got ");
192 1.1.1.5 mrg mpfr_dump (x2);
193 1.1.1.5 mrg printf ("with inex = %d and flags =", inex2);
194 1.1.1.5 mrg flags_out (flags2);
195 1.1.1.5 mrg exit (1);
196 1.1.1.5 mrg }
197 1.1.1.5 mrg }
198 1.1.1.5 mrg
199 1.1.1.5 mrg mpfr_clears (x1, x2, y, (mpfr_ptr) 0);
200 1.1.1.5 mrg }
201 1.1.1.5 mrg
202 1.1.1.5 mrg static void
203 1.1.1.5 mrg test_2exp_extreme (void)
204 1.1.1.5 mrg {
205 1.1.1.5 mrg mpfr_exp_t emin, emax;
206 1.1.1.5 mrg
207 1.1.1.5 mrg emin = mpfr_get_emin ();
208 1.1.1.5 mrg emax = mpfr_get_emax ();
209 1.1.1.5 mrg
210 1.1.1.5 mrg set_emin (MPFR_EMIN_MIN);
211 1.1.1.5 mrg set_emax (MPFR_EMAX_MAX);
212 1.1.1.5 mrg test_2exp_extreme_aux ();
213 1.1.1.5 mrg
214 1.1.1.5 mrg set_emin (-REXP);
215 1.1.1.5 mrg set_emax (REXP);
216 1.1.1.5 mrg test_2exp_extreme_aux ();
217 1.1.1.5 mrg
218 1.1.1.5 mrg set_emin (emin);
219 1.1.1.5 mrg set_emax (emax);
220 1.1.1.5 mrg }
221 1.1.1.5 mrg
222 1.1 mrg static void
223 1.1 mrg test_macros (void)
224 1.1 mrg {
225 1.1 mrg mpfr_t x[3];
226 1.1 mrg mpfr_ptr p;
227 1.1 mrg int r;
228 1.1 mrg
229 1.1.1.4 mrg /* Note: the ++'s below allow one to check that the corresponding
230 1.1.1.4 mrg arguments are evaluated only once by the macros. */
231 1.1.1.4 mrg
232 1.1 mrg mpfr_inits (x[0], x[1], x[2], (mpfr_ptr) 0);
233 1.1 mrg p = x[0];
234 1.1 mrg r = 0;
235 1.1 mrg mpfr_set_ui (p++, 0, (mpfr_rnd_t) r++);
236 1.1 mrg if (p != x[1] || r != 1)
237 1.1 mrg {
238 1.1 mrg printf ("Error in mpfr_set_ui macro: p - x[0] = %d (expecting 1), "
239 1.1 mrg "r = %d (expecting 1)\n", (int) (p - x[0]), r);
240 1.1 mrg exit (1);
241 1.1 mrg }
242 1.1 mrg p = x[0];
243 1.1 mrg r = 0;
244 1.1 mrg mpfr_set_si (p++, 0, (mpfr_rnd_t) r++);
245 1.1 mrg if (p != x[1] || r != 1)
246 1.1 mrg {
247 1.1 mrg printf ("Error in mpfr_set_si macro: p - x[0] = %d (expecting 1), "
248 1.1 mrg "r = %d (expecting 1)\n", (int) (p - x[0]), r);
249 1.1 mrg exit (1);
250 1.1 mrg }
251 1.1 mrg mpfr_clears (x[0], x[1], x[2], (mpfr_ptr) 0);
252 1.1 mrg }
253 1.1 mrg
254 1.1.1.2 mrg static void
255 1.1.1.2 mrg test_macros_keyword (void)
256 1.1.1.2 mrg {
257 1.1.1.2 mrg mpfr_t x;
258 1.1.1.2 mrg unsigned long i;
259 1.1.1.2 mrg
260 1.1.1.2 mrg mpfr_init2 (x, 64);
261 1.1.1.2 mrg #define MKN 0x1000000
262 1.1.1.2 mrg #define long short
263 1.1.1.2 mrg mpfr_set_ui (x, MKN, MPFR_RNDN);
264 1.1.1.2 mrg #undef long
265 1.1.1.2 mrg i = mpfr_get_ui (x, MPFR_RNDN);
266 1.1.1.2 mrg if (i != MKN)
267 1.1.1.2 mrg {
268 1.1.1.2 mrg printf ("Error in test_macros_keyword: expected 0x%lx, got 0x%lx.\n",
269 1.1.1.2 mrg (unsigned long) MKN, i);
270 1.1.1.2 mrg exit (1);
271 1.1.1.2 mrg }
272 1.1.1.2 mrg mpfr_clear (x);
273 1.1.1.2 mrg }
274 1.1.1.2 mrg
275 1.1.1.4 mrg static void
276 1.1.1.4 mrg test_get_ui_smallneg (void)
277 1.1.1.4 mrg {
278 1.1.1.4 mrg mpfr_t x;
279 1.1.1.4 mrg int i;
280 1.1.1.4 mrg
281 1.1.1.4 mrg mpfr_init2 (x, 64);
282 1.1.1.4 mrg
283 1.1.1.4 mrg for (i = 1; i <= 4; i++)
284 1.1.1.4 mrg {
285 1.1.1.4 mrg int r;
286 1.1.1.4 mrg
287 1.1.1.4 mrg mpfr_set_si_2exp (x, -i, -2, MPFR_RNDN);
288 1.1.1.4 mrg RND_LOOP (r)
289 1.1.1.4 mrg {
290 1.1.1.4 mrg long s;
291 1.1.1.4 mrg unsigned long u;
292 1.1.1.4 mrg
293 1.1.1.4 mrg mpfr_clear_erangeflag ();
294 1.1.1.4 mrg s = mpfr_get_si (x, r != MPFR_RNDF ? (mpfr_rnd_t) r : MPFR_RNDA);
295 1.1.1.4 mrg if (mpfr_erangeflag_p ())
296 1.1.1.4 mrg {
297 1.1.1.4 mrg printf ("ERROR for get_si + ERANGE + small negative op"
298 1.1.1.4 mrg " for rnd = %s and x = -%d/4\n",
299 1.1.1.4 mrg mpfr_print_rnd_mode ((mpfr_rnd_t) r), i);
300 1.1.1.4 mrg exit (1);
301 1.1.1.4 mrg }
302 1.1.1.4 mrg u = mpfr_get_ui (x, (mpfr_rnd_t) r);
303 1.1.1.4 mrg if (u != 0)
304 1.1.1.4 mrg {
305 1.1.1.4 mrg printf ("ERROR for get_ui + ERANGE + small negative op"
306 1.1.1.4 mrg " for rnd = %s and x = -%d/4\n",
307 1.1.1.4 mrg mpfr_print_rnd_mode ((mpfr_rnd_t) r), i);
308 1.1.1.4 mrg printf ("Expected 0, got %lu\n", u);
309 1.1.1.4 mrg exit (1);
310 1.1.1.4 mrg }
311 1.1.1.4 mrg if ((s == 0) ^ !mpfr_erangeflag_p ())
312 1.1.1.4 mrg {
313 1.1.1.4 mrg const char *Not = s == 0 ? "" : " not";
314 1.1.1.4 mrg
315 1.1.1.4 mrg printf ("ERROR for get_ui + ERANGE + small negative op"
316 1.1.1.4 mrg " for rnd = %s and x = -%d/4\n",
317 1.1.1.4 mrg mpfr_print_rnd_mode ((mpfr_rnd_t) r), i);
318 1.1.1.4 mrg printf ("The rounding integer (%ld) is%s representable in "
319 1.1.1.4 mrg "unsigned long,\nbut the erange flag is%s set.\n",
320 1.1.1.4 mrg s, Not, Not);
321 1.1.1.4 mrg exit (1);
322 1.1.1.4 mrg }
323 1.1.1.4 mrg }
324 1.1.1.4 mrg }
325 1.1.1.4 mrg
326 1.1.1.4 mrg mpfr_clear (x);
327 1.1.1.4 mrg }
328 1.1.1.4 mrg
329 1.1.1.4 mrg /* Test mpfr_get_si and mpfr_get_ui, on values around some particular
330 1.1.1.4 mrg * integers (see ts[] and tu[]): x = t?[i] + j/4, where '?' is 's' or
331 1.1.1.4 mrg * 'u', and j is an integer from -8 to 8.
332 1.1.1.4 mrg */
333 1.1.1.4 mrg static void get_tests (void)
334 1.1.1.4 mrg {
335 1.1.1.4 mrg mpfr_exp_t emin, emax;
336 1.1.1.4 mrg mpfr_t x, z;
337 1.1.1.4 mrg long ts[5] = { LONG_MIN, LONG_MAX, -17, 0, 17 };
338 1.1.1.4 mrg unsigned long tu[3] = { 0, ULONG_MAX, 17 };
339 1.1.1.4 mrg int s, i, j, odd, ctr = 0;
340 1.1.1.4 mrg int inex;
341 1.1.1.4 mrg int r;
342 1.1.1.4 mrg
343 1.1.1.4 mrg emin = mpfr_get_emin ();
344 1.1.1.4 mrg emax = mpfr_get_emax ();
345 1.1.1.4 mrg
346 1.1.1.4 mrg /* We need the bitsize of an unsigned long + 3 bits (1 additional bit for
347 1.1.1.4 mrg * the cases >= ULONG_MAX + 1; 2 additional bits for the fractional part).
348 1.1.1.4 mrg */
349 1.1.1.4 mrg mpfr_init2 (x, sizeof (unsigned long) * CHAR_BIT + 3);
350 1.1.1.4 mrg
351 1.1.1.4 mrg mpfr_init2 (z, MPFR_PREC_MIN);
352 1.1.1.4 mrg mpfr_set_ui_2exp (z, 1, -2, MPFR_RNDN); /* z = 1/4 */
353 1.1.1.4 mrg
354 1.1.1.4 mrg for (s = 1; s >= 0; s--)
355 1.1.1.4 mrg for (i = 0; i < (s ? 5 : 3); i++)
356 1.1.1.4 mrg {
357 1.1.1.4 mrg odd = (s ? (unsigned long) ts[i] : tu[i]) & 1;
358 1.1.1.4 mrg inex = s ?
359 1.1.1.4 mrg mpfr_set_si (x, ts[i], MPFR_RNDN) :
360 1.1.1.4 mrg mpfr_set_ui (x, tu[i], MPFR_RNDN);
361 1.1.1.4 mrg MPFR_ASSERTN (inex == 0);
362 1.1.1.4 mrg inex = mpfr_sub_ui (x, x, 2, MPFR_RNDN);
363 1.1.1.4 mrg MPFR_ASSERTN (inex == 0);
364 1.1.1.4 mrg for (j = -8; j <= 8; j++)
365 1.1.1.4 mrg {
366 1.1.1.4 mrg /* Test x = t?[i] + j/4 in each non-RNDF rounding mode... */
367 1.1.1.4 mrg RND_LOOP_NO_RNDF (r)
368 1.1.1.4 mrg {
369 1.1.1.4 mrg mpfr_flags_t ex_flags, flags;
370 1.1.1.4 mrg int e, k, overflow;
371 1.1.1.4 mrg
372 1.1.1.4 mrg ctr++; /* for the check below */
373 1.1.1.4 mrg
374 1.1.1.4 mrg /* Let's determine k such that the rounded integer should
375 1.1.1.4 mrg be t?[i] + k, assuming an unbounded exponent range. */
376 1.1.1.4 mrg k = (j + 8 +
377 1.1.1.4 mrg (MPFR_IS_LIKE_RNDD (r, MPFR_SIGN (x)) ? 0 :
378 1.1.1.4 mrg MPFR_IS_LIKE_RNDU (r, MPFR_SIGN (x)) ? 3 :
379 1.1.1.4 mrg 2)) / 4 - 2;
380 1.1.1.4 mrg if (r == MPFR_RNDN && ((unsigned int) j & 3) == 2 &&
381 1.1.1.4 mrg ((odd + k) & 1))
382 1.1.1.4 mrg k--; /* even rounding */
383 1.1.1.4 mrg
384 1.1.1.4 mrg /* Overflow cases. Note that with the above choices:
385 1.1.1.4 mrg _ t?[0] == minval(type)
386 1.1.1.4 mrg _ t?[1] == maxval(type)
387 1.1.1.4 mrg */
388 1.1.1.4 mrg overflow = (i == 0 && k < 0) || (i == 1 && k > 0);
389 1.1.1.4 mrg
390 1.1.1.4 mrg /* Expected flags. Note that in case of overflow, only the
391 1.1.1.4 mrg erange flag is set. Otherwise, the result is inexact iff
392 1.1.1.4 mrg j mod 1 != 0, i.e. the last two bits are not 00. */
393 1.1.1.4 mrg ex_flags = overflow ? MPFR_FLAGS_ERANGE
394 1.1.1.4 mrg : ((unsigned int) j & 3) != 0 ? MPFR_FLAGS_INEXACT : 0;
395 1.1.1.4 mrg
396 1.1.1.4 mrg mpfr_clear_flags ();
397 1.1.1.4 mrg
398 1.1.1.4 mrg #define GET_TESTS_TEST(TYPE,TZ,F,C,FMT) \
399 1.1.1.4 mrg do { \
400 1.1.1.4 mrg TYPE a, d; \
401 1.1.1.4 mrg \
402 1.1.1.4 mrg a = TZ[i] + (overflow ? 0 : k); \
403 1.1.1.4 mrg if (e) \
404 1.1.1.4 mrg { \
405 1.1.1.4 mrg mpfr_exp_t ex; \
406 1.1.1.4 mrg ex = MPFR_GET_EXP (x); \
407 1.1.1.4 mrg set_emin (ex); \
408 1.1.1.4 mrg set_emax (ex); \
409 1.1.1.4 mrg } \
410 1.1.1.4 mrg d = F (x, (mpfr_rnd_t) r); \
411 1.1.1.4 mrg flags = __gmpfr_flags; \
412 1.1.1.4 mrg set_emin (emin); \
413 1.1.1.4 mrg set_emax (emax); \
414 1.1.1.4 mrg if (flags != ex_flags || a != d) \
415 1.1.1.4 mrg { \
416 1.1.1.4 mrg printf ("Error in get_tests for " #F " on %s%s\n", \
417 1.1.1.4 mrg mpfr_print_rnd_mode ((mpfr_rnd_t) r), \
418 1.1.1.4 mrg e ? ", reduced exponent range" : ""); \
419 1.1.1.4 mrg printf ("x = t" C "[%d] + (%d/4) = ", i, j); \
420 1.1.1.4 mrg mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); \
421 1.1.1.4 mrg printf ("\n--> k = %d\n", k); \
422 1.1.1.4 mrg printf ("Expected %l" FMT "\n", a); \
423 1.1.1.4 mrg printf ("Got %l" FMT "\n", d); \
424 1.1.1.4 mrg printf ("Expected flags:"); \
425 1.1.1.4 mrg flags_out (ex_flags); \
426 1.1.1.4 mrg printf ("Got flags: "); \
427 1.1.1.4 mrg flags_out (flags); \
428 1.1.1.4 mrg exit (1); \
429 1.1.1.4 mrg } \
430 1.1.1.4 mrg } while (0)
431 1.1.1.4 mrg
432 1.1.1.4 mrg for (e = 0; e < 2; e++)
433 1.1.1.4 mrg {
434 1.1.1.4 mrg if (e && MPFR_IS_ZERO (x))
435 1.1.1.4 mrg break;
436 1.1.1.4 mrg if (s)
437 1.1.1.4 mrg GET_TESTS_TEST (long,
438 1.1.1.4 mrg ts, mpfr_get_si, "s", "d");
439 1.1.1.4 mrg else
440 1.1.1.4 mrg GET_TESTS_TEST (unsigned long,
441 1.1.1.4 mrg tu, mpfr_get_ui, "u", "u");
442 1.1.1.4 mrg }
443 1.1.1.4 mrg }
444 1.1.1.4 mrg inex = mpfr_add (x, x, z, MPFR_RNDN);
445 1.1.1.4 mrg MPFR_ASSERTN (inex == 0);
446 1.1.1.4 mrg }
447 1.1.1.4 mrg }
448 1.1.1.4 mrg
449 1.1.1.4 mrg /* Check that we have tested everything: 8 = 5 + 3 integers t?[i]
450 1.1.1.4 mrg * with 17 = 8 - (-8) + 1 additional terms (j/4) for each integer,
451 1.1.1.4 mrg * and each non-RNDF rounding mode.
452 1.1.1.4 mrg */
453 1.1.1.4 mrg MPFR_ASSERTN (ctr == 8 * 17 * ((int) MPFR_RND_MAX - 1));
454 1.1.1.4 mrg
455 1.1.1.4 mrg mpfr_clear (x);
456 1.1.1.4 mrg mpfr_clear (z);
457 1.1.1.4 mrg }
458 1.1.1.4 mrg
459 1.1 mrg /* FIXME: Comparing against mpfr_get_si/ui is not ideal, it'd be better to
460 1.1 mrg have all tests examine the bits in mpfr_t for what should come out. */
461 1.1 mrg
462 1.1 mrg int
463 1.1 mrg main (int argc, char *argv[])
464 1.1 mrg {
465 1.1 mrg mpfr_t x;
466 1.1 mrg long k, z, d, N;
467 1.1 mrg unsigned long zl, dl;
468 1.1 mrg int inex;
469 1.1 mrg int r;
470 1.1 mrg mpfr_exp_t emin, emax;
471 1.1 mrg int flag;
472 1.1 mrg
473 1.1 mrg tests_start_mpfr ();
474 1.1 mrg
475 1.1.1.4 mrg get_tests ();
476 1.1.1.4 mrg
477 1.1 mrg mpfr_init2 (x, 100);
478 1.1 mrg
479 1.1.1.4 mrg N = (argc == 1) ? 100000 : atol (argv[1]);
480 1.1 mrg
481 1.1 mrg for (k = 1; k <= N; k++)
482 1.1 mrg {
483 1.1 mrg z = (long) (randlimb () & LONG_MAX) + LONG_MIN / 2;
484 1.1 mrg inex = mpfr_set_si (x, z, MPFR_RNDZ);
485 1.1 mrg d = mpfr_get_si (x, MPFR_RNDZ);
486 1.1 mrg if (d != z)
487 1.1 mrg {
488 1.1 mrg printf ("Error in mpfr_set_si: expected %ld got %ld\n", z, d);
489 1.1 mrg exit (1);
490 1.1 mrg }
491 1.1 mrg if (inex)
492 1.1 mrg {
493 1.1 mrg printf ("Error in mpfr_set_si: inex value incorrect for %ld: %d\n",
494 1.1 mrg z, inex);
495 1.1 mrg exit (1);
496 1.1 mrg }
497 1.1 mrg }
498 1.1 mrg
499 1.1 mrg for (k = 1; k <= N; k++)
500 1.1 mrg {
501 1.1 mrg zl = randlimb ();
502 1.1 mrg inex = mpfr_set_ui (x, zl, MPFR_RNDZ);
503 1.1 mrg dl = mpfr_get_ui (x, MPFR_RNDZ);
504 1.1 mrg if (dl != zl)
505 1.1 mrg {
506 1.1 mrg printf ("Error in mpfr_set_ui: expected %lu got %lu\n", zl, dl);
507 1.1 mrg exit (1);
508 1.1 mrg }
509 1.1 mrg if (inex)
510 1.1 mrg {
511 1.1 mrg printf ("Error in mpfr_set_ui: inex value incorrect for %lu: %d\n",
512 1.1 mrg zl, inex);
513 1.1 mrg exit (1);
514 1.1 mrg }
515 1.1 mrg }
516 1.1 mrg
517 1.1 mrg mpfr_set_prec (x, 2);
518 1.1 mrg if (mpfr_set_si (x, 5, MPFR_RNDZ) >= 0)
519 1.1 mrg {
520 1.1 mrg printf ("Wrong inexact flag for x=5, rnd=MPFR_RNDZ\n");
521 1.1 mrg exit (1);
522 1.1 mrg }
523 1.1 mrg
524 1.1 mrg mpfr_set_prec (x, 2);
525 1.1 mrg if (mpfr_set_si (x, -5, MPFR_RNDZ) <= 0)
526 1.1 mrg {
527 1.1 mrg printf ("Wrong inexact flag for x=-5, rnd=MPFR_RNDZ\n");
528 1.1 mrg exit (1);
529 1.1 mrg }
530 1.1 mrg
531 1.1 mrg mpfr_set_prec (x, 3);
532 1.1 mrg inex = mpfr_set_si (x, 77617, MPFR_RNDD); /* should be 65536 */
533 1.1.1.4 mrg if (MPFR_MANT(x)[0] != MPFR_LIMB_HIGHBIT || inex >= 0)
534 1.1 mrg {
535 1.1 mrg printf ("Error in mpfr_set_si(x:3, 77617, MPFR_RNDD)\n");
536 1.1.1.4 mrg mpfr_dump (x);
537 1.1 mrg exit (1);
538 1.1 mrg }
539 1.1 mrg inex = mpfr_set_ui (x, 77617, MPFR_RNDD); /* should be 65536 */
540 1.1.1.4 mrg if (MPFR_MANT(x)[0] != MPFR_LIMB_HIGHBIT || inex >= 0)
541 1.1 mrg {
542 1.1 mrg printf ("Error in mpfr_set_ui(x:3, 77617, MPFR_RNDD)\n");
543 1.1.1.4 mrg mpfr_dump (x);
544 1.1 mrg exit (1);
545 1.1 mrg }
546 1.1 mrg
547 1.1 mrg mpfr_set_prec (x, 2);
548 1.1 mrg inex = mpfr_set_si (x, 33096, MPFR_RNDU);
549 1.1 mrg if (mpfr_get_si (x, MPFR_RNDZ) != 49152 || inex <= 0)
550 1.1 mrg {
551 1.1 mrg printf ("Error in mpfr_set_si, exp. 49152, got %ld, inex %d\n",
552 1.1 mrg mpfr_get_si (x, MPFR_RNDZ), inex);
553 1.1 mrg exit (1);
554 1.1 mrg }
555 1.1 mrg inex = mpfr_set_ui (x, 33096, MPFR_RNDU);
556 1.1 mrg if (mpfr_get_si (x, MPFR_RNDZ) != 49152)
557 1.1 mrg {
558 1.1 mrg printf ("Error in mpfr_set_ui, exp. 49152, got %ld, inex %d\n",
559 1.1 mrg mpfr_get_si (x, MPFR_RNDZ), inex);
560 1.1 mrg exit (1);
561 1.1 mrg }
562 1.1.1.2 mrg /* Also test the mpfr_set_ui function (instead of macro). */
563 1.1.1.2 mrg inex = (mpfr_set_ui) (x, 33096, MPFR_RNDU);
564 1.1.1.2 mrg if (mpfr_get_si (x, MPFR_RNDZ) != 49152)
565 1.1.1.2 mrg {
566 1.1.1.2 mrg printf ("Error in mpfr_set_ui function, exp. 49152, got %ld, inex %d\n",
567 1.1.1.2 mrg mpfr_get_si (x, MPFR_RNDZ), inex);
568 1.1.1.2 mrg exit (1);
569 1.1.1.2 mrg }
570 1.1 mrg
571 1.1 mrg for (r = 0 ; r < MPFR_RND_MAX ; r++)
572 1.1 mrg {
573 1.1 mrg mpfr_set_si (x, -1, (mpfr_rnd_t) r);
574 1.1 mrg mpfr_set_ui (x, 0, (mpfr_rnd_t) r);
575 1.1 mrg if (MPFR_IS_NEG (x) || mpfr_get_ui (x, (mpfr_rnd_t) r) != 0)
576 1.1 mrg {
577 1.1 mrg printf ("mpfr_set_ui (x, 0) gives -0 for %s\n",
578 1.1 mrg mpfr_print_rnd_mode ((mpfr_rnd_t) r));
579 1.1 mrg exit (1);
580 1.1 mrg }
581 1.1 mrg
582 1.1 mrg mpfr_set_si (x, -1, (mpfr_rnd_t) r);
583 1.1 mrg mpfr_set_si (x, 0, (mpfr_rnd_t) r);
584 1.1 mrg if (MPFR_IS_NEG (x) || mpfr_get_si (x, (mpfr_rnd_t) r) != 0)
585 1.1 mrg {
586 1.1 mrg printf ("mpfr_set_si (x, 0) gives -0 for %s\n",
587 1.1 mrg mpfr_print_rnd_mode ((mpfr_rnd_t) r));
588 1.1 mrg exit (1);
589 1.1 mrg }
590 1.1 mrg }
591 1.1 mrg
592 1.1 mrg /* check potential bug in case mp_limb_t is unsigned */
593 1.1 mrg emax = mpfr_get_emax ();
594 1.1 mrg set_emax (0);
595 1.1 mrg mpfr_set_si (x, -1, MPFR_RNDN);
596 1.1 mrg if (mpfr_sgn (x) >= 0)
597 1.1 mrg {
598 1.1 mrg printf ("mpfr_set_si (x, -1) fails\n");
599 1.1 mrg exit (1);
600 1.1 mrg }
601 1.1 mrg set_emax (emax);
602 1.1 mrg
603 1.1 mrg emax = mpfr_get_emax ();
604 1.1 mrg set_emax (5);
605 1.1 mrg mpfr_set_prec (x, 2);
606 1.1 mrg mpfr_set_si (x, -31, MPFR_RNDN);
607 1.1 mrg if (mpfr_sgn (x) >= 0)
608 1.1 mrg {
609 1.1 mrg printf ("mpfr_set_si (x, -31) fails\n");
610 1.1 mrg exit (1);
611 1.1 mrg }
612 1.1 mrg set_emax (emax);
613 1.1 mrg
614 1.1 mrg /* test for get_ui */
615 1.1 mrg mpfr_set_ui (x, 0, MPFR_RNDN);
616 1.1 mrg MPFR_ASSERTN(mpfr_get_ui (x, MPFR_RNDN) == 0);
617 1.1 mrg mpfr_set_ui (x, ULONG_MAX, MPFR_RNDU);
618 1.1 mrg mpfr_nextabove (x);
619 1.1 mrg mpfr_get_ui (x, MPFR_RNDU);
620 1.1 mrg
621 1.1 mrg /* another test for get_ui */
622 1.1 mrg mpfr_set_prec (x, 10);
623 1.1 mrg mpfr_set_str_binary (x, "10.101");
624 1.1 mrg dl = mpfr_get_ui (x, MPFR_RNDN);
625 1.1 mrg MPFR_ASSERTN (dl == 3);
626 1.1 mrg
627 1.1 mrg mpfr_set_str_binary (x, "-1.0");
628 1.1 mrg mpfr_get_ui (x, MPFR_RNDN);
629 1.1 mrg
630 1.1 mrg mpfr_set_str_binary (x, "0.1");
631 1.1 mrg dl = mpfr_get_ui (x, MPFR_RNDN);
632 1.1 mrg MPFR_ASSERTN (dl == 0);
633 1.1 mrg dl = mpfr_get_ui (x, MPFR_RNDZ);
634 1.1 mrg MPFR_ASSERTN (dl == 0);
635 1.1 mrg dl = mpfr_get_ui (x, MPFR_RNDD);
636 1.1 mrg MPFR_ASSERTN (dl == 0);
637 1.1 mrg dl = mpfr_get_ui (x, MPFR_RNDU);
638 1.1 mrg MPFR_ASSERTN (dl == 1);
639 1.1 mrg
640 1.1 mrg /* coverage tests */
641 1.1 mrg mpfr_set_prec (x, 2);
642 1.1 mrg mpfr_set_si (x, -7, MPFR_RNDD);
643 1.1 mrg MPFR_ASSERTN(mpfr_cmp_si (x, -8) == 0);
644 1.1 mrg mpfr_set_prec (x, 2);
645 1.1 mrg mpfr_set_ui (x, 7, MPFR_RNDU);
646 1.1 mrg MPFR_ASSERTN(mpfr_cmp_ui (x, 8) == 0);
647 1.1 mrg emax = mpfr_get_emax ();
648 1.1 mrg set_emax (3);
649 1.1 mrg mpfr_set_ui (x, 7, MPFR_RNDU);
650 1.1 mrg MPFR_ASSERTN(mpfr_inf_p (x) && mpfr_sgn (x) > 0);
651 1.1 mrg set_emax (1);
652 1.1 mrg MPFR_ASSERTN( mpfr_set_ui (x, 7, MPFR_RNDU) );
653 1.1 mrg MPFR_ASSERTN(mpfr_inf_p (x) && mpfr_sgn (x) > 0);
654 1.1 mrg set_emax (emax);
655 1.1 mrg mpfr_set_ui_2exp (x, 17, -50, MPFR_RNDN);
656 1.1 mrg MPFR_ASSERTN (mpfr_get_ui (x, MPFR_RNDD) == 0);
657 1.1 mrg MPFR_ASSERTN (mpfr_get_si (x, MPFR_RNDD) == 0);
658 1.1 mrg
659 1.1.1.4 mrg /* Test for ERANGE flag + correct behavior if overflow */
660 1.1 mrg mpfr_set_prec (x, 256);
661 1.1 mrg mpfr_set_ui (x, ULONG_MAX, MPFR_RNDN);
662 1.1 mrg mpfr_clear_erangeflag ();
663 1.1 mrg dl = mpfr_get_ui (x, MPFR_RNDN);
664 1.1 mrg if (dl != ULONG_MAX || mpfr_erangeflag_p ())
665 1.1 mrg {
666 1.1 mrg printf ("ERROR for get_ui + ERANGE + ULONG_MAX (1)\n");
667 1.1 mrg exit (1);
668 1.1 mrg }
669 1.1 mrg mpfr_add_ui (x, x, 1, MPFR_RNDN);
670 1.1 mrg dl = mpfr_get_ui (x, MPFR_RNDN);
671 1.1 mrg if (dl != ULONG_MAX || !mpfr_erangeflag_p ())
672 1.1 mrg {
673 1.1 mrg printf ("ERROR for get_ui + ERANGE + ULONG_MAX (2)\n");
674 1.1 mrg exit (1);
675 1.1 mrg }
676 1.1 mrg mpfr_set_si (x, -1, MPFR_RNDN);
677 1.1 mrg mpfr_clear_erangeflag ();
678 1.1 mrg dl = mpfr_get_ui (x, MPFR_RNDN);
679 1.1 mrg if (dl != 0 || !mpfr_erangeflag_p ())
680 1.1 mrg {
681 1.1 mrg printf ("ERROR for get_ui + ERANGE + -1 \n");
682 1.1 mrg exit (1);
683 1.1 mrg }
684 1.1 mrg mpfr_set_si (x, LONG_MAX, MPFR_RNDN);
685 1.1 mrg mpfr_clear_erangeflag ();
686 1.1 mrg d = mpfr_get_si (x, MPFR_RNDN);
687 1.1 mrg if (d != LONG_MAX || mpfr_erangeflag_p ())
688 1.1 mrg {
689 1.1 mrg printf ("ERROR for get_si + ERANGE + LONG_MAX (1): %ld\n", d);
690 1.1 mrg exit (1);
691 1.1 mrg }
692 1.1 mrg mpfr_add_ui (x, x, 1, MPFR_RNDN);
693 1.1 mrg d = mpfr_get_si (x, MPFR_RNDN);
694 1.1 mrg if (d != LONG_MAX || !mpfr_erangeflag_p ())
695 1.1 mrg {
696 1.1 mrg printf ("ERROR for get_si + ERANGE + LONG_MAX (2)\n");
697 1.1 mrg exit (1);
698 1.1 mrg }
699 1.1 mrg mpfr_set_si (x, LONG_MIN, MPFR_RNDN);
700 1.1 mrg mpfr_clear_erangeflag ();
701 1.1 mrg d = mpfr_get_si (x, MPFR_RNDN);
702 1.1 mrg if (d != LONG_MIN || mpfr_erangeflag_p ())
703 1.1 mrg {
704 1.1 mrg printf ("ERROR for get_si + ERANGE + LONG_MIN (1)\n");
705 1.1 mrg exit (1);
706 1.1 mrg }
707 1.1 mrg mpfr_sub_ui (x, x, 1, MPFR_RNDN);
708 1.1 mrg d = mpfr_get_si (x, MPFR_RNDN);
709 1.1 mrg if (d != LONG_MIN || !mpfr_erangeflag_p ())
710 1.1 mrg {
711 1.1 mrg printf ("ERROR for get_si + ERANGE + LONG_MIN (2)\n");
712 1.1 mrg exit (1);
713 1.1 mrg }
714 1.1 mrg
715 1.1 mrg mpfr_set_nan (x);
716 1.1.1.4 mrg mpfr_clear_flags ();
717 1.1 mrg d = mpfr_get_ui (x, MPFR_RNDN);
718 1.1.1.4 mrg if (d != 0 || __gmpfr_flags != MPFR_FLAGS_ERANGE)
719 1.1 mrg {
720 1.1 mrg printf ("ERROR for get_ui + NaN\n");
721 1.1 mrg exit (1);
722 1.1 mrg }
723 1.1 mrg mpfr_clear_erangeflag ();
724 1.1 mrg d = mpfr_get_si (x, MPFR_RNDN);
725 1.1.1.4 mrg if (d != 0 || __gmpfr_flags != MPFR_FLAGS_ERANGE)
726 1.1 mrg {
727 1.1 mrg printf ("ERROR for get_si + NaN\n");
728 1.1 mrg exit (1);
729 1.1 mrg }
730 1.1 mrg
731 1.1 mrg emin = mpfr_get_emin ();
732 1.1 mrg mpfr_set_prec (x, 2);
733 1.1 mrg
734 1.1 mrg mpfr_set_emin (4);
735 1.1 mrg mpfr_clear_flags ();
736 1.1 mrg mpfr_set_ui (x, 7, MPFR_RNDU);
737 1.1 mrg flag = mpfr_underflow_p ();
738 1.1 mrg mpfr_set_emin (emin);
739 1.1 mrg if (mpfr_cmp_ui (x, 8) != 0)
740 1.1 mrg {
741 1.1 mrg printf ("Error for mpfr_set_ui (x, 7, MPFR_RNDU), prec = 2, emin = 4\n");
742 1.1 mrg exit (1);
743 1.1 mrg }
744 1.1 mrg if (flag)
745 1.1 mrg {
746 1.1 mrg printf ("mpfr_set_ui (x, 7, MPFR_RNDU) should not underflow "
747 1.1 mrg "with prec = 2, emin = 4\n");
748 1.1 mrg exit (1);
749 1.1 mrg }
750 1.1 mrg
751 1.1 mrg mpfr_set_emin (4);
752 1.1 mrg mpfr_clear_flags ();
753 1.1 mrg mpfr_set_si (x, -7, MPFR_RNDD);
754 1.1 mrg flag = mpfr_underflow_p ();
755 1.1 mrg mpfr_set_emin (emin);
756 1.1 mrg if (mpfr_cmp_si (x, -8) != 0)
757 1.1 mrg {
758 1.1 mrg printf ("Error for mpfr_set_si (x, -7, MPFR_RNDD), prec = 2, emin = 4\n");
759 1.1 mrg exit (1);
760 1.1 mrg }
761 1.1 mrg if (flag)
762 1.1 mrg {
763 1.1 mrg printf ("mpfr_set_si (x, -7, MPFR_RNDD) should not underflow "
764 1.1 mrg "with prec = 2, emin = 4\n");
765 1.1 mrg exit (1);
766 1.1 mrg }
767 1.1 mrg
768 1.1 mrg mpfr_clear (x);
769 1.1 mrg
770 1.1 mrg test_2exp ();
771 1.1.1.5 mrg test_2exp_extreme ();
772 1.1 mrg test_macros ();
773 1.1.1.2 mrg test_macros_keyword ();
774 1.1.1.4 mrg test_get_ui_smallneg ();
775 1.1 mrg tests_end_mpfr ();
776 1.1 mrg return 0;
777 1.1 mrg }
778