1 /* Test file for mpfr_sub1sp.
2
3 Copyright 2003-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 check_special (void);
26 static void check_random (mpfr_prec_t p);
27 static void check_underflow (mpfr_prec_t p);
28 static void check_corner (mpfr_prec_t p);
29
30 static void
bug20170109(void)31 bug20170109 (void)
32 {
33 mpfr_t a, b, c;
34
35 mpfr_init2 (a, 111);
36 mpfr_init2 (b, 111);
37 mpfr_init2 (c, 111);
38 mpfr_set_str_binary (b, "0.110010010000111111011010101000100010000101101000110000100011010011000100110001100110001010001011100000001101110E1");
39 mpfr_set_str_binary (c, "0.111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111E-63");
40 mpfr_sub (a, b, c, MPFR_RNDN);
41 mpfr_set_str_binary (b, "0.110010010000111111011010101000100010000101101000110000100011001111000100110001100110001010001011100000001101110E1");
42 MPFR_ASSERTN(mpfr_equal_p (a, b));
43 mpfr_clear (a);
44 mpfr_clear (b);
45 mpfr_clear (c);
46 }
47
48 /* check mpfr_sub1sp1 when:
49 (1) p = GMP_NUMB_BITS-1, d = GMP_NUMB_BITS and bp[0] = MPFR_LIMB_HIGHBIT
50 (2) p = 2*GMP_NUMB_BITS-1, d = 2*GMP_NUMB_BITS and b = 1000...000
51 (3) p = 3*GMP_NUMB_BITS-1, d = 3*GMP_NUMB_BITS and b = 1000...000
52 */
53 static void
test20170208(void)54 test20170208 (void)
55 {
56 mpfr_t a, b, c;
57 int inex;
58
59 mpfr_inits2 (GMP_NUMB_BITS - 1, a, b, c, (mpfr_ptr) 0);
60
61 /* test (1) */
62 mpfr_set_ui_2exp (b, 1, GMP_NUMB_BITS, MPFR_RNDN);
63 mpfr_set_ui_2exp (c, 1, 0, MPFR_RNDN);
64 inex = mpfr_sub (a, b, c, MPFR_RNDN);
65 /* b-c = 2^GMP_NUMB_BITS-1 which has GMP_NUMB_BITS bits, thus we should
66 round to 2^GMP_NUMB_BITS (even rule) */
67 MPFR_ASSERTN(mpfr_cmp_ui_2exp (a, 1, GMP_NUMB_BITS) == 0);
68 MPFR_ASSERTN(inex > 0);
69 inex = mpfr_sub1sp (a, b, c, MPFR_RNDN);
70 MPFR_ASSERTN(mpfr_cmp_ui_2exp (a, 1, GMP_NUMB_BITS) == 0);
71 MPFR_ASSERTN(inex > 0);
72
73 mpfr_set_ui_2exp (c, 2, 0, MPFR_RNDN);
74 mpfr_nextbelow (c);
75 /* now c = 2 - 2^(1-GMP_NUMB_BITS) */
76 inex = mpfr_sub (a, b, c, MPFR_RNDN);
77 /* b-c = 2^GMP_NUMB_BITS-2+2^(1-GMP_NUMB_BITS), which should
78 round to 2^GMP_NUMB_BITS-2. We check by directly inspecting the bit
79 field of a, since mpfr_cmp_ui might not work if unsigned long is shorter
80 than mp_limb_t, and we don't want to use mpfr_add_ui or mpfr_sub_ui
81 to construct the expected result. */
82 MPFR_ASSERTN(MPFR_MANT(a)[0] == (mp_limb_t) -2);
83 MPFR_ASSERTN(MPFR_EXP(a) == GMP_NUMB_BITS);
84 MPFR_ASSERTN(inex < 0);
85 inex = mpfr_sub1sp (a, b, c, MPFR_RNDN);
86 MPFR_ASSERTN(MPFR_MANT(a)[0] == (mp_limb_t) -2);
87 MPFR_ASSERTN(MPFR_EXP(a) == GMP_NUMB_BITS);
88 MPFR_ASSERTN(inex < 0);
89
90 /* test (2) */
91 mpfr_set_prec (a, 2 * GMP_NUMB_BITS - 1);
92 mpfr_set_prec (b, 2 * GMP_NUMB_BITS - 1);
93 mpfr_set_prec (c, 2 * GMP_NUMB_BITS - 1);
94 mpfr_set_ui_2exp (b, 1, 2 * GMP_NUMB_BITS, MPFR_RNDN);
95 mpfr_set_ui_2exp (c, 1, 0, MPFR_RNDN);
96 inex = mpfr_sub (a, b, c, MPFR_RNDN);
97 /* b-c = 2^(2*GMP_NUMB_BITS)-1 which has 2*GMP_NUMB_BITS bits, thus we should
98 round to 2^(2*GMP_NUMB_BITS) (even rule) */
99 MPFR_ASSERTN(mpfr_cmp_ui_2exp (a, 1, 2 * GMP_NUMB_BITS) == 0);
100 MPFR_ASSERTN(inex > 0);
101 inex = mpfr_sub1sp (a, b, c, MPFR_RNDN);
102 MPFR_ASSERTN(mpfr_cmp_ui_2exp (a, 1, 2 * GMP_NUMB_BITS) == 0);
103 MPFR_ASSERTN(inex > 0);
104
105 mpfr_set_ui_2exp (c, 2, 0, MPFR_RNDN);
106 mpfr_nextbelow (c);
107 /* now c = 2 - 2^(1-2*GMP_NUMB_BITS) */
108 inex = mpfr_sub (a, b, c, MPFR_RNDN);
109 /* b-c = 2^(2*GMP_NUMB_BITS)-2+2^(1-2*GMP_NUMB_BITS), which should
110 round to 2^(2*GMP_NUMB_BITS)-2. We check by directly inspecting the bit
111 field of a, since mpfr_cmp_ui might not work if unsigned long is shorter
112 than mp_limb_t, and we don't want to use mpfr_add_ui or mpfr_sub_ui
113 to construct the expected result. */
114 MPFR_ASSERTN(MPFR_MANT(a)[1] == (mp_limb_t) -1);
115 MPFR_ASSERTN(MPFR_MANT(a)[0] == (mp_limb_t) -2);
116 MPFR_ASSERTN(MPFR_EXP(a) == 2 * GMP_NUMB_BITS);
117 MPFR_ASSERTN(inex < 0);
118 inex = mpfr_sub1sp (a, b, c, MPFR_RNDN);
119 MPFR_ASSERTN(MPFR_MANT(a)[1] == (mp_limb_t) -1);
120 MPFR_ASSERTN(MPFR_MANT(a)[0] == (mp_limb_t) -2);
121 MPFR_ASSERTN(MPFR_EXP(a) == 2 * GMP_NUMB_BITS);
122 MPFR_ASSERTN(inex < 0);
123
124 /* test (3) */
125 mpfr_set_prec (a, 3 * GMP_NUMB_BITS - 1);
126 mpfr_set_prec (b, 3 * GMP_NUMB_BITS - 1);
127 mpfr_set_prec (c, 3 * GMP_NUMB_BITS - 1);
128 mpfr_set_ui_2exp (b, 1, 3 * GMP_NUMB_BITS, MPFR_RNDN);
129 mpfr_set_ui_2exp (c, 1, 0, MPFR_RNDN);
130 inex = mpfr_sub (a, b, c, MPFR_RNDN);
131 /* b-c = 2^(3*GMP_NUMB_BITS)-1 which has 3*GMP_NUMB_BITS bits, thus we should
132 round to 3^(2*GMP_NUMB_BITS) (even rule) */
133 MPFR_ASSERTN(mpfr_cmp_ui_2exp (a, 1, 3 * GMP_NUMB_BITS) == 0);
134 MPFR_ASSERTN(inex > 0);
135 inex = mpfr_sub1sp (a, b, c, MPFR_RNDN);
136 MPFR_ASSERTN(mpfr_cmp_ui_2exp (a, 1, 3 * GMP_NUMB_BITS) == 0);
137 MPFR_ASSERTN(inex > 0);
138
139 mpfr_set_ui_2exp (c, 2, 0, MPFR_RNDN);
140 mpfr_nextbelow (c);
141 /* now c = 2 - 2^(1-3*GMP_NUMB_BITS) */
142 inex = mpfr_sub (a, b, c, MPFR_RNDN);
143 /* b-c = 2^(3*GMP_NUMB_BITS)-2+2^(1-3*GMP_NUMB_BITS), which should
144 round to 2^(3*GMP_NUMB_BITS)-2. We check by directly inspecting the bit
145 field of a, since mpfr_cmp_ui might not work if unsigned long is shorter
146 than mp_limb_t, and we don't want to use mpfr_add_ui or mpfr_sub_ui
147 to construct the expected result. */
148 MPFR_ASSERTN(MPFR_MANT(a)[2] == (mp_limb_t) -1);
149 MPFR_ASSERTN(MPFR_MANT(a)[1] == (mp_limb_t) -1);
150 MPFR_ASSERTN(MPFR_MANT(a)[0] == (mp_limb_t) -2);
151 MPFR_ASSERTN(MPFR_EXP(a) == 3 * GMP_NUMB_BITS);
152 MPFR_ASSERTN(inex < 0);
153 inex = mpfr_sub1sp (a, b, c, MPFR_RNDN);
154 MPFR_ASSERTN(MPFR_MANT(a)[2] == (mp_limb_t) -1);
155 MPFR_ASSERTN(MPFR_MANT(a)[1] == (mp_limb_t) -1);
156 MPFR_ASSERTN(MPFR_MANT(a)[0] == (mp_limb_t) -2);
157 MPFR_ASSERTN(MPFR_EXP(a) == 3 * GMP_NUMB_BITS);
158 MPFR_ASSERTN(inex < 0);
159
160 mpfr_clears (a, b, c, (mpfr_ptr) 0);
161 }
162
163 static void
compare_sub_sub1sp(void)164 compare_sub_sub1sp (void)
165 {
166 mpfr_t a, b, c, a_ref;
167 mpfr_prec_t p;
168 unsigned long d;
169 int i, inex_ref, inex;
170 int r;
171
172 for (p = 1; p <= 3*GMP_NUMB_BITS; p++)
173 {
174 mpfr_inits2 (p, a, b, c, a_ref, (mpfr_ptr) 0);
175 for (d = 0; d <= p + 2; d++)
176 {
177 /* EXP(b) - EXP(c) = d */
178 for (i = 0; i < 4; i++)
179 {
180 /* for i even, b is the smallest number, for b odd the largest */
181 mpfr_set_ui_2exp (b, 1, d, MPFR_RNDN);
182 if (i & 1)
183 {
184 mpfr_mul_2ui (b, b, 1, MPFR_RNDN);
185 mpfr_nextbelow (b);
186 }
187 mpfr_set_ui_2exp (c, 1, 0, MPFR_RNDN);
188 if (i & 2)
189 {
190 mpfr_mul_2ui (c, c, 1, MPFR_RNDN);
191 mpfr_nextbelow (c);
192 }
193 RND_LOOP_NO_RNDF (r)
194 {
195 /* increase the precision of b to ensure sub1sp is not used */
196 mpfr_prec_round (b, p + 1, MPFR_RNDN);
197 inex_ref = mpfr_sub (a_ref, b, c, (mpfr_rnd_t) r);
198 inex = mpfr_prec_round (b, p, MPFR_RNDN);
199 MPFR_ASSERTN(inex == 0);
200 inex = mpfr_sub1sp (a, b, c, (mpfr_rnd_t) r);
201 if (inex != inex_ref)
202 {
203 printf ("mpfr_sub and mpfr_sub1sp differ for r=%s\n",
204 mpfr_print_rnd_mode ((mpfr_rnd_t) r));
205 printf ("b="); mpfr_dump (b);
206 printf ("c="); mpfr_dump (c);
207 printf ("expected inex=%d and ", inex_ref);
208 mpfr_dump (a_ref);
209 printf ("got inex=%d and ", inex);
210 mpfr_dump (a);
211 exit (1);
212 }
213 MPFR_ASSERTN(mpfr_equal_p (a, a_ref));
214 }
215 }
216 }
217 mpfr_clears (a, b, c, a_ref, (mpfr_ptr) 0);
218 }
219 }
220
221 static void
bug20171213(void)222 bug20171213 (void)
223 {
224 mpfr_t a, b, c;
225
226 mpfr_init2 (a, 127);
227 mpfr_init2 (b, 127);
228 mpfr_init2 (c, 127);
229 mpfr_set_str_binary (b, "0.1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E1");
230 mpfr_set_str_binary (c, "0.1000011010111101100101100110101111111001011001010000110000000000000000000000000000000000000000000000000000000000000000000000000E-74");
231 mpfr_sub (a, b, c, MPFR_RNDN);
232 mpfr_set_str_binary (b, "0.1111111111111111111111111111111111111111111111111111111111111111111111111101111001010000100110100110010100000001101001101011110E0");
233 MPFR_ASSERTN(mpfr_equal_p (a, b));
234 mpfr_clear (a);
235 mpfr_clear (b);
236 mpfr_clear (c);
237 }
238
239 /* generic test for bug20171213:
240 b = 1.0 with precision p
241 c = 0.1xxx110...0E-e with precision p, with e >= 1, such that the part 1xxx1 has
242 exactly p+1-e bits, thus b-c = 0.111..01... is exact on p+1 bits.
243 Due to the round-to-even rule, b-c should be rounded to 0.111..0.
244 */
245 static void
bug20171213_gen(mpfr_prec_t pmax)246 bug20171213_gen (mpfr_prec_t pmax)
247 {
248 mpfr_prec_t p;
249 mpfr_exp_t e;
250 mpfr_t a, b, c, d;
251
252 for (p = MPFR_PREC_MIN; p <= pmax; p++)
253 {
254 for (e = 1; e < p; e++)
255 {
256 mpfr_init2 (a, p);
257 mpfr_init2 (b, p);
258 mpfr_init2 (c, p);
259 mpfr_init2 (d, p);
260 mpfr_set_ui (b, 1, MPFR_RNDN);
261 mpfr_set_ui_2exp (c, 1, p + 1 - e, MPFR_RNDN); /* c = 2^(p + 1 - e) */
262 mpfr_sub_ui (c, c, 1, MPFR_RNDN); /* c = 2^(p + 1 - e) - 1 */
263 mpfr_div_2ui (c, c, p + 1, MPFR_RNDN); /* c = 2^(-e) - 2^(-p-1) */
264 /* the exact difference is 1 - 2^(-e) + 2^(-p-1) */
265 mpfr_sub (a, b, c, MPFR_RNDN);
266 /* check that a = 1 - 2^(-e) */
267 mpfr_set_ui_2exp (d, 1, e, MPFR_RNDN); /* b = 2^e */
268 mpfr_sub_ui (d, d, 1, MPFR_RNDN); /* b = 2^e - 1 */
269 mpfr_div_2ui (d, d, e, MPFR_RNDN); /* b = 1 - 2^(-e) */
270 if (! mpfr_equal_p (a, d))
271 {
272 printf ("bug20171213_gen failed for p=%ld, e=%ld\n",
273 (long) p, (long) e);
274 printf ("b="); mpfr_dump (b);
275 printf ("c="); mpfr_dump (c);
276 printf ("got a="); mpfr_dump (a);
277 printf ("expected d="); mpfr_dump (d);
278 exit (1);
279 }
280 mpfr_clear (a);
281 mpfr_clear (b);
282 mpfr_clear (c);
283 mpfr_clear (d);
284 }
285 }
286 }
287
288 static void
coverage(void)289 coverage (void)
290 {
291 mpfr_t a, b, c, d, u;
292 int inex;
293
294 /* coverage test in mpfr_sub1sp: case d=1, limb > MPFR_LIMB_HIGHBIT, RNDF
295 and also RNDZ */
296 mpfr_init2 (a, 3 * GMP_NUMB_BITS);
297 mpfr_init2 (b, 3 * GMP_NUMB_BITS);
298 mpfr_init2 (c, 3 * GMP_NUMB_BITS);
299 mpfr_init2 (d, 3 * GMP_NUMB_BITS);
300 mpfr_init2 (u, 3 * GMP_NUMB_BITS);
301 mpfr_set_ui (b, 1, MPFR_RNDN);
302 mpfr_nextbelow (b); /* b = 1 - 2^(-p) */
303 mpfr_set_prec (c, GMP_NUMB_BITS);
304 mpfr_set_ui_2exp (c, 1, -1, MPFR_RNDN);
305 mpfr_nextbelow (c);
306 mpfr_nextbelow (c); /* c = 1/2 - 2*2^(-GMP_NUMB_BITS-1) */
307 mpfr_prec_round (c, 3 * GMP_NUMB_BITS, MPFR_RNDN);
308 mpfr_nextbelow (c); /* c = 1/2 - 2*2^(-GMP_NUMB_BITS-1) - 2^(-p-1) */
309 /* b-c = c */
310 mpfr_sub (a, b, c, MPFR_RNDF);
311 mpfr_sub (d, b, c, MPFR_RNDD);
312 mpfr_sub (u, b, c, MPFR_RNDU);
313 /* check a = d or u */
314 MPFR_ASSERTN(mpfr_equal_p (a, d) || mpfr_equal_p (a, u));
315
316 /* coverage test in mpfr_sub1sp: case d=p, RNDN, sb = 0, significand of b
317 is even but b<>2^e, (case 1e) */
318 mpfr_set_prec (a, 3 * GMP_NUMB_BITS);
319 mpfr_set_prec (b, 3 * GMP_NUMB_BITS);
320 mpfr_set_prec (c, 3 * GMP_NUMB_BITS);
321 mpfr_set_ui (b, 1, MPFR_RNDN);
322 mpfr_nextabove (b);
323 mpfr_nextabove (b);
324 mpfr_set_ui_2exp (c, 1, -3 * GMP_NUMB_BITS, MPFR_RNDN);
325 inex = mpfr_sub (a, b, c, MPFR_RNDN);
326 MPFR_ASSERTN(inex > 0);
327 MPFR_ASSERTN(mpfr_equal_p (a, b));
328
329 mpfr_clear (a);
330 mpfr_clear (b);
331 mpfr_clear (c);
332 mpfr_clear (d);
333 mpfr_clear (u);
334 }
335
336 /* bug in mpfr_sub1sp1n, made generic */
337 static void
bug20180217(mpfr_prec_t pmax)338 bug20180217 (mpfr_prec_t pmax)
339 {
340 mpfr_t a, b, c;
341 int inex;
342 mpfr_prec_t p;
343
344 for (p = MPFR_PREC_MIN; p <= pmax; p++)
345 {
346 mpfr_init2 (a, p);
347 mpfr_init2 (b, p);
348 mpfr_init2 (c, p);
349 mpfr_set_ui (b, 1, MPFR_RNDN); /* b = 1 */
350 mpfr_set_ui_2exp (c, 1, -p-1, MPFR_RNDN); /* c = 2^(-p-1) */
351 /* a - b = 1 - 2^(-p-1) and should be rounded to 1 (case 2f of
352 mpfr_sub1sp) */
353 inex = mpfr_sub (a, b, c, MPFR_RNDN);
354 MPFR_ASSERTN(inex > 0);
355 MPFR_ASSERTN(mpfr_cmp_ui (a, 1) == 0);
356 /* check also when a=b */
357 mpfr_set_ui (a, 1, MPFR_RNDN);
358 inex = mpfr_sub (a, a, c, MPFR_RNDN);
359 MPFR_ASSERTN(inex > 0);
360 MPFR_ASSERTN(mpfr_cmp_ui (a, 1) == 0);
361 /* and when a=c */
362 mpfr_set_ui (b, 1, MPFR_RNDN); /* b = 1 */
363 mpfr_set_ui_2exp (a, 1, -p-1, MPFR_RNDN);
364 inex = mpfr_sub (a, b, a, MPFR_RNDN);
365 MPFR_ASSERTN(inex > 0);
366 MPFR_ASSERTN(mpfr_cmp_ui (a, 1) == 0);
367 mpfr_clear (a);
368 mpfr_clear (b);
369 mpfr_clear (c);
370 }
371 }
372
373 /* bug in revision 12985 with tlog and GMP_CHECK_RANDOMIZE=1534111552615050
374 (introduced in revision 12242, does not affect the 4.0 branch) */
375 static void
bug20180813(void)376 bug20180813 (void)
377 {
378 mpfr_t a, b, c;
379
380 mpfr_init2 (a, 194);
381 mpfr_init2 (b, 194);
382 mpfr_init2 (c, 194);
383 mpfr_set_str_binary (b, "0.10000111101000100000010000100010110111011100110100000101100111000010101000110110010101011101101011110110001000111001000010110010111010010100011011010100001010001110000101000010101110100110001000E7");
384 mpfr_set_str_binary (c, "0.10000000000000000100001111010001000000100001000101101110111001101000001011001110000101010001101100101010111011010111101100010001110010000101100101110100101000110110101000010100011100001010000101E24");
385 mpfr_sub (a, b, c, MPFR_RNDN);
386 mpfr_set_str_binary (b, "-0.11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111E23");
387 MPFR_ASSERTN(mpfr_equal_p (a, b));
388 mpfr_clear (a);
389 mpfr_clear (b);
390 mpfr_clear (c);
391 }
392
393 /* bug in revision 13599 with tatan and GMP_CHECK_RANDOMIZE=1567609230659336:
394 the values are equal, but the ternary value differs between sub1 and sub1sp
395 (bug introduced with mpfr_sub1sp2n, does not affect the 4.0 branch) */
396 static void
bug20190904(void)397 bug20190904 (void)
398 {
399 mpfr_t a, b, c;
400 int ret;
401
402 mpfr_init2 (a, 128);
403 mpfr_init2 (b, 128);
404 mpfr_init2 (c, 128);
405 mpfr_set_str_binary (b, "0.11001001000011111101101010100010001000010110100011000010001101001100010011000110011000101000101110000000110111000001110011010001E1");
406 mpfr_set_str_binary (c, "0.10010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010010000000000000000000000E-102");
407 ret = mpfr_sub (a, b, c, MPFR_RNDN);
408 mpfr_set_str_binary (b, "0.11001001000011111101101010100010001000010110100011000010001101001100010011000110011000101000101101111111101111000001110011010001E1");
409 MPFR_ASSERTN(mpfr_equal_p (a, b));
410 MPFR_ASSERTN(ret > 0);
411 mpfr_clear (a);
412 mpfr_clear (b);
413 mpfr_clear (c);
414 }
415
416 int
main(void)417 main (void)
418 {
419 mpfr_prec_t p;
420
421 tests_start_mpfr ();
422
423 bug20190904 ();
424 bug20180813 ();
425 bug20180217 (1024);
426 coverage ();
427 compare_sub_sub1sp ();
428 test20170208 ();
429 bug20170109 ();
430 bug20171213 ();
431 bug20171213_gen (256);
432 check_special ();
433 for (p = MPFR_PREC_MIN ; p < 200 ; p++)
434 {
435 check_underflow (p);
436 check_random (p);
437 check_corner (p);
438 }
439
440 tests_end_mpfr ();
441 return 0;
442 }
443
444 #define STD_ERROR \
445 do \
446 { \
447 printf("ERROR: for %s and p=%lu and i=%d:\nY=", \
448 mpfr_print_rnd_mode ((mpfr_rnd_t) r), (unsigned long) p, i); \
449 mpfr_dump (y); \
450 printf ("Z="); mpfr_dump (z); \
451 printf ("Expected: "); mpfr_dump (x2); \
452 printf ("Got : "); mpfr_dump (x); \
453 abort(); \
454 } \
455 while (0)
456
457 #define STD_ERROR2 \
458 do \
459 { \
460 printf("ERROR: for %s and p=%lu and i=%d:\nY=", \
461 mpfr_print_rnd_mode ((mpfr_rnd_t) r), (unsigned long) p, i); \
462 mpfr_dump (y); \
463 printf ("Z="); mpfr_dump (z); \
464 printf ("Expected: "); mpfr_dump (x2); \
465 printf ("Got : "); mpfr_dump (x); \
466 printf ("Wrong inexact flag. Expected %d. Got %d\n", \
467 inexact1, inexact2); \
468 exit(1); \
469 } \
470 while (0)
471
472 static void
check_random(mpfr_prec_t p)473 check_random (mpfr_prec_t p)
474 {
475 mpfr_t x,y,z,x2;
476 int r;
477 int i, inexact1, inexact2;
478
479 mpfr_inits2 (p, x, y, z, x2, (mpfr_ptr) 0);
480
481 for (i = 0 ; i < 500 ; i++)
482 {
483 mpfr_urandomb (y, RANDS);
484 mpfr_urandomb (z, RANDS);
485 if (MPFR_IS_PURE_FP(y) && MPFR_IS_PURE_FP(z))
486 RND_LOOP (r)
487 {
488 if (r == MPFR_RNDF)
489 continue; /* mpfr_sub1 and mpfr_sub1sp could differ,
490 and inexact makes no sense */
491 inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
492 inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
493 if (mpfr_cmp(x, x2))
494 STD_ERROR;
495 if (inexact1 != inexact2)
496 STD_ERROR2;
497 }
498 }
499
500 mpfr_clears (x, y, z, x2, (mpfr_ptr) 0);
501 }
502
503 static void
check_special(void)504 check_special (void)
505 {
506 mpfr_t x,y,z,x2;
507 int r;
508 mpfr_prec_t p;
509 int i = -1, inexact1, inexact2;
510 mpfr_exp_t es;
511
512 mpfr_inits (x, y, z, x2, (mpfr_ptr) 0);
513
514 RND_LOOP (r)
515 {
516 if (r == MPFR_RNDF)
517 continue; /* comparison between sub1 and sub1sp makes no sense here */
518
519 p = 53;
520 mpfr_set_prec(x, 53);
521 mpfr_set_prec(x2, 53);
522 mpfr_set_prec(y, 53);
523 mpfr_set_prec(z, 53);
524
525 mpfr_set_str_binary (y,
526 "0.10110111101101110010010010011011000001101101011011001E31");
527
528 mpfr_sub1sp (x, y, y, (mpfr_rnd_t) r);
529 if (mpfr_cmp_ui(x, 0))
530 {
531 printf("Error for x-x with p=%lu. Expected 0. Got:",
532 (unsigned long) p);
533 mpfr_dump (x);
534 exit(1);
535 }
536
537 mpfr_set(z, y, (mpfr_rnd_t) r);
538 mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
539 if (mpfr_cmp_ui(x, 0))
540 {
541 printf("Error for x-y with y=x and p=%lu. Expected 0. Got:",
542 (unsigned long) p);
543 mpfr_dump (x);
544 exit(1);
545 }
546 /* diff = 0 */
547 mpfr_set_str_binary (y,
548 "0.10110111101101110010010010011011001001101101011011001E31");
549 inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
550 inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
551 if (mpfr_cmp(x, x2))
552 STD_ERROR;
553 if (inexact1 != inexact2)
554 STD_ERROR2;
555
556 /* Diff = 1 */
557 mpfr_set_str_binary (y,
558 "0.10110111101101110010010010011011000001101101011011001E30");
559 inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
560 inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
561 if (mpfr_cmp(x, x2))
562 STD_ERROR;
563 if (inexact1 != inexact2)
564 STD_ERROR2;
565
566 /* Diff = 2 */
567 mpfr_set_str_binary (y,
568 "0.10110111101101110010010010011011000101101101011011001E32");
569 inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
570 inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
571 if (mpfr_cmp(x, x2))
572 STD_ERROR;
573 if (inexact1 != inexact2)
574 STD_ERROR2;
575
576 /* Diff = 32 */
577 mpfr_set_str_binary (y,
578 "0.10110111101101110010010010011011000001101101011011001E63");
579 inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
580 inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
581 if (mpfr_cmp(x, x2))
582 STD_ERROR;
583 if (inexact1 != inexact2)
584 STD_ERROR2;
585
586 /* Diff = 52 */
587 mpfr_set_str_binary (y,
588 "0.10110111101101110010010010011011010001101101011011001E83");
589 inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
590 inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
591 if (mpfr_cmp(x, x2))
592 STD_ERROR;
593 if (inexact1 != inexact2)
594 STD_ERROR2;
595
596 /* Diff = 53 */
597 mpfr_set_str_binary (y,
598 "0.10110111101101110010010010011111000001101101011011001E31");
599 inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
600 inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
601 if (mpfr_cmp(x, x2))
602 STD_ERROR;
603 if (inexact1 != inexact2)
604 STD_ERROR2;
605
606 /* Diff > 200 */
607 mpfr_set_str_binary (y,
608 "0.10110111101101110010010010011011000001101101011011001E331");
609 inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
610 inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
611 if (mpfr_cmp(x, x2))
612 STD_ERROR;
613 if (inexact1 != inexact2)
614 STD_ERROR2;
615
616 mpfr_set_str_binary (y,
617 "0.10000000000000000000000000000000000000000000000000000E31");
618 mpfr_set_str_binary (z,
619 "0.11111111111111111111111111111111111111111111111111111E30");
620 inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
621 inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
622 if (mpfr_cmp(x, x2))
623 STD_ERROR;
624 if (inexact1 != inexact2)
625 STD_ERROR2;
626
627 mpfr_set_str_binary (y,
628 "0.10000000000000000000000000000000000000000000000000000E31");
629 mpfr_set_str_binary (z,
630 "0.11111111111111111111111111111111111111111111111111111E29");
631 inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
632 inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
633 if (mpfr_cmp(x, x2))
634 STD_ERROR;
635 if (inexact1 != inexact2)
636 STD_ERROR2;
637
638 mpfr_set_str_binary (y,
639 "0.10000000000000000000000000000000000000000000000000000E52");
640 mpfr_set_str_binary (z,
641 "0.10000000000010000000000000000000000000000000000000000E00");
642 inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
643 inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
644 if (mpfr_cmp(x, x2))
645 STD_ERROR;
646 if (inexact1 != inexact2)
647 STD_ERROR2;
648
649 mpfr_set_str_binary (y,
650 "0.11100000000000000000000000000000000000000000000000000E53");
651 mpfr_set_str_binary (z,
652 "0.10000000000000000000000000000000000000000000000000000E00");
653 inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
654 inexact2 = mpfr_sub1sp(z, y, z, (mpfr_rnd_t) r);
655 mpfr_set(x, z, (mpfr_rnd_t) r);
656 if (mpfr_cmp(x, x2))
657 STD_ERROR;
658 if (inexact1 != inexact2)
659 STD_ERROR2;
660
661 mpfr_set_str_binary (y,
662 "0.10000000000000000000000000000000000000000000000000000E53");
663 mpfr_set_str_binary (z,
664 "0.10100000000000000000000000000000000000000000000000000E00");
665 inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
666 inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
667 if (mpfr_cmp(x, x2))
668 STD_ERROR;
669 if (inexact1 != inexact2)
670 STD_ERROR2;
671
672 mpfr_set_str_binary (y,
673 "0.10000000000000000000000000000000000000000000000000000E54");
674 mpfr_set_str_binary (z,
675 "0.10100000000000000000000000000000000000000000000000000E00");
676 inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
677 inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
678 if (mpfr_cmp(x, x2))
679 STD_ERROR;
680 if (inexact1 != inexact2)
681 STD_ERROR2;
682
683 p = 63;
684 mpfr_set_prec(x, p);
685 mpfr_set_prec(x2, p);
686 mpfr_set_prec(y, p);
687 mpfr_set_prec(z, p);
688 mpfr_set_str_binary (y,
689 "0.100000000000000000000000000000000000000000000000000000000000000E62");
690 mpfr_set_str_binary (z,
691 "0.110000000000000000000000000000000000000000000000000000000000000E00");
692 inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
693 inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
694 if (mpfr_cmp(x, x2))
695 STD_ERROR;
696 if (inexact1 != inexact2)
697 STD_ERROR2;
698
699 p = 64;
700 mpfr_set_prec(x, 64);
701 mpfr_set_prec(x2, 64);
702 mpfr_set_prec(y, 64);
703 mpfr_set_prec(z, 64);
704
705 mpfr_set_str_binary (y,
706 "0.1100000000000000000000000000000000000000000000000000000000000000E31");
707 mpfr_set_str_binary (z,
708 "0.1111111111111111111111111110000000000000000000000000011111111111E29");
709 inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
710 inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
711 if (mpfr_cmp(x, x2))
712 STD_ERROR;
713 if (inexact1 != inexact2)
714 STD_ERROR2;
715
716 mpfr_set_str_binary (y,
717 "0.1000000000000000000000000000000000000000000000000000000000000000E63");
718 mpfr_set_str_binary (z,
719 "0.1011000000000000000000000000000000000000000000000000000000000000E00");
720 inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
721 inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
722 if (mpfr_cmp(x, x2))
723 STD_ERROR;
724 if (inexact1 != inexact2)
725 STD_ERROR2;
726
727 mpfr_set_str_binary (y,
728 "0.1000000000000000000000000000000000000000000000000000000000000000E63");
729 mpfr_set_str_binary (z,
730 "0.1110000000000000000000000000000000000000000000000000000000000000E00");
731 inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
732 inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
733 if (mpfr_cmp(x, x2))
734 STD_ERROR;
735 if (inexact1 != inexact2)
736 STD_ERROR2;
737
738 mpfr_set_str_binary (y,
739 "0.10000000000000000000000000000000000000000000000000000000000000E63");
740 mpfr_set_str_binary (z,
741 "0.10000000000000000000000000000000000000000000000000000000000000E00");
742 inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
743 inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
744 if (mpfr_cmp(x, x2))
745 STD_ERROR;
746 if (inexact1 != inexact2)
747 STD_ERROR2;
748
749 mpfr_set_str_binary (y,
750 "0.1000000000000000000000000000000000000000000000000000000000000000E64");
751 mpfr_set_str_binary (z,
752 "0.1010000000000000000000000000000000000000000000000000000000000000E00");
753 inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
754 inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
755 if (mpfr_cmp(x, x2))
756 STD_ERROR;
757 if (inexact1 != inexact2)
758 STD_ERROR2;
759
760 MPFR_SET_NAN(x);
761 MPFR_SET_NAN(x2);
762 mpfr_set_str_binary (y,
763 "0.1000000000000000000000000000000000000000000000000000000000000000"
764 "E-1073741823");
765 mpfr_set_str_binary (z,
766 "0.1100000000000000000000000000000000000000000000000000000000000000"
767 "E-1073741823");
768 inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
769 inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
770 if (mpfr_cmp(x, x2))
771 STD_ERROR;
772 if (inexact1 != inexact2)
773 STD_ERROR2;
774
775 p = 9;
776 mpfr_set_prec(x, p);
777 mpfr_set_prec(x2, p);
778 mpfr_set_prec(y, p);
779 mpfr_set_prec(z, p);
780
781 mpfr_set_str_binary (y, "0.100000000E1");
782 mpfr_set_str_binary (z, "0.100000000E-8");
783 inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
784 inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
785 if (mpfr_cmp(x, x2))
786 STD_ERROR;
787 if (inexact1 != inexact2)
788 STD_ERROR2;
789
790 p = 34;
791 mpfr_set_prec(x, p);
792 mpfr_set_prec(x2, p);
793 mpfr_set_prec(y, p);
794 mpfr_set_prec(z, p);
795
796 mpfr_set_str_binary (y, "-0.1011110000111100010111011100110100E-18");
797 mpfr_set_str_binary (z, "0.1000101010110011010101011110000000E-14");
798 inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
799 inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
800 if (mpfr_cmp(x, x2))
801 STD_ERROR;
802 if (inexact1 != inexact2)
803 STD_ERROR2;
804
805 p = 124;
806 mpfr_set_prec(x, p);
807 mpfr_set_prec(x2, p);
808 mpfr_set_prec(y, p);
809 mpfr_set_prec(z, p);
810
811 mpfr_set_str_binary (y,
812 "0.1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E1");
813 mpfr_set_str_binary (z,
814 "0.1011111000100111000011001000011101010101101100101010101001000001110100001101110110001110111010000011101001100010111110001100E-31");
815 inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
816 inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
817 if (mpfr_cmp(x, x2))
818 STD_ERROR;
819 if (inexact1 != inexact2)
820 STD_ERROR2;
821
822 p = 288;
823 mpfr_set_prec(x, p);
824 mpfr_set_prec(x2, p);
825 mpfr_set_prec(y, p);
826 mpfr_set_prec(z, p);
827
828 mpfr_set_str_binary (y,
829 "0.111000110011000001000111101010111011110011101001101111111110000011100101000001001010110010101010011001010100000001110011110001010101101010001011101110100100001011110100110000101101100011010001001011011010101010000010001101001000110010010111111011110001111101001000101101001100101100101000E80");
830 mpfr_set_str_binary (z,
831 "-0.100001111111101001011010001100110010100111001110000110011101001011010100001000000100111011010110110010000000000010101101011000010000110001110010100001100101011100100100001011000100011110000001010101000100011101001000010111100000111000111011001000100100011000100000010010111000000100100111E-258");
832 inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
833 inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
834 if (mpfr_cmp(x, x2))
835 STD_ERROR;
836 if (inexact1 != inexact2)
837 STD_ERROR2;
838
839 p = 85;
840 mpfr_set_prec(x, p);
841 mpfr_set_prec(x2, p);
842 mpfr_set_prec(y, p);
843 mpfr_set_prec(z, p);
844
845 mpfr_set_str_binary (y,
846 "0.1111101110100110110110100010101011101001100010100011110110110010010011101100101111100E-4");
847 mpfr_set_str_binary (z,
848 "0.1111101110100110110110100010101001001000011000111000011101100101110100001110101010110E-4");
849 inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
850 inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
851 if (mpfr_cmp(x, x2))
852 STD_ERROR;
853 if (inexact1 != inexact2)
854 STD_ERROR2;
855
856 p = 64;
857 mpfr_set_prec(x, p); mpfr_set_prec(x2, p);
858 mpfr_set_prec(y, p); mpfr_set_prec(z, p);
859
860 mpfr_set_str_binary (y,
861 "0.11000000000000000000000000000000"
862 "00000000000000000000000000000000E1");
863 mpfr_set_str_binary (z,
864 "0.10000000000000000000000000000000"
865 "00000000000000000000000000000001E0");
866 inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
867 inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
868 if (mpfr_cmp(x, x2))
869 STD_ERROR;
870 if (inexact1 != inexact2)
871 STD_ERROR2;
872
873 mpfr_set_str_binary (y,
874 "0.11000000000000000000000000000000"
875 "000000000000000000000000000001E1");
876 mpfr_set_str_binary (z,
877 "0.10000000000000000000000000000000"
878 "00000000000000000000000000000001E0");
879 inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
880 inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
881 if (mpfr_cmp(x, x2))
882 STD_ERROR;
883 if (inexact1 != inexact2)
884 STD_ERROR2;
885
886 es = mpfr_get_emin ();
887 set_emin (-1024);
888
889 mpfr_set_str_binary (y,
890 "0.10000000000000000000000000000000"
891 "000000000000000000000000000000E-1023");
892 mpfr_set_str_binary (z,
893 "0.10000000000000000000000000000000"
894 "00000000000000000000000000000001E-1023");
895 inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
896 inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
897 if (mpfr_cmp(x, x2))
898 STD_ERROR;
899 if (inexact1 != inexact2)
900 STD_ERROR2;
901
902 mpfr_set_str_binary (y,
903 "0.10000000000000000000000000000000"
904 "000000000000000000000000000000E-1023");
905 mpfr_set_str_binary (z,
906 "0.1000000000000000000000000000000"
907 "000000000000000000000000000000E-1023");
908 inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
909 inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
910 if (mpfr_cmp(x, x2))
911 STD_ERROR;
912 if (inexact1 != inexact2)
913 STD_ERROR2;
914
915 set_emin (es);
916 }
917
918 mpfr_clears (x, y, z, x2, (mpfr_ptr) 0);
919 }
920
921 static void
check_underflow(mpfr_prec_t p)922 check_underflow (mpfr_prec_t p)
923 {
924 mpfr_t x, y, z;
925 int inexact;
926
927 mpfr_inits2 (p, x, y, z, (mpfr_ptr) 0);
928
929 if (p >= 2) /* we need p >= 2 so that 3 is exact */
930 {
931 mpfr_set_ui_2exp (y, 4, mpfr_get_emin () - 2, MPFR_RNDN);
932 mpfr_set_ui_2exp (z, 3, mpfr_get_emin () - 2, MPFR_RNDN);
933 inexact = mpfr_sub (x, y, z, MPFR_RNDN);
934 if (inexact >= 0 || (mpfr_cmp_ui (x, 0) != 0))
935 {
936 printf ("4*2^(emin-2) - 3*2^(emin-2) with RNDN failed for p=%ld\n",
937 (long) p);
938 printf ("Expected inexact < 0 with x=0\n");
939 printf ("Got inexact=%d with x=", inexact);
940 mpfr_dump (x);
941 exit (1);
942 }
943 }
944
945 if (p >= 3) /* we need p >= 3 so that 5 is exact */
946 {
947 mpfr_set_ui_2exp (y, 5, mpfr_get_emin () - 2, MPFR_RNDN);
948 mpfr_set_ui_2exp (z, 4, mpfr_get_emin () - 2, MPFR_RNDN);
949 inexact = mpfr_sub (x, y, z, MPFR_RNDN);
950 if (inexact >= 0 || (mpfr_cmp_ui (x, 0) != 0))
951 {
952 printf ("5*2^(emin-2) - 4*2^(emin-2) with RNDN failed for p=%ld\n",
953 (long) p);
954 printf ("Expected inexact < 0 with x=0\n");
955 printf ("Got inexact=%d with x=", inexact);
956 mpfr_dump (x);
957 exit (1);
958 }
959 }
960
961 mpfr_clears (x, y, z, (mpfr_ptr) 0);
962 }
963
964 /* check corner cases of mpfr_sub1sp in case d = 1 and limb = MPFR_LIMB_HIGHBIT */
965 static void
check_corner(mpfr_prec_t p)966 check_corner (mpfr_prec_t p)
967 {
968 mpfr_t x, y, z;
969 mpfr_exp_t e;
970 int inex, odd;
971
972 if (p < 4) /* ensures that the initial value of z is > 1 below */
973 return;
974
975 mpfr_inits2 (p, x, y, z, (mpfr_ptr) 0);
976 mpfr_const_pi (y, MPFR_RNDN);
977 mpfr_set_ui (z, 2, MPFR_RNDN);
978 inex = mpfr_sub (z, y, z, MPFR_RNDN); /* z is near pi-2, thus y-z is near 2 */
979 MPFR_ASSERTN(inex == 0);
980 for (e = 0; e < p; e++)
981 {
982 /* add 2^(-e) to z */
983 mpfr_mul_2ui (z, z, e, MPFR_RNDN);
984 inex = mpfr_add_ui (z, z, 1, MPFR_RNDN);
985 MPFR_ASSERTN(inex == 0);
986 mpfr_div_2ui (z, z, e, MPFR_RNDN);
987
988 /* compute x = y - z which should be exact, near 2-2^(-e) */
989 inex = mpfr_sub (x, y, z, MPFR_RNDN);
990 MPFR_ASSERTN(inex == 0);
991 MPFR_ASSERTN(mpfr_get_exp (x) == 1);
992
993 /* restore initial z */
994 mpfr_mul_2ui (z, z, e, MPFR_RNDN);
995 inex = mpfr_sub_ui (z, z, 1, MPFR_RNDN);
996 MPFR_ASSERTN(inex == 0);
997 mpfr_div_2ui (z, z, e, MPFR_RNDN);
998
999 /* subtract 2^(-e) to z */
1000 mpfr_mul_2ui (z, z, e, MPFR_RNDN);
1001 inex = mpfr_sub_ui (z, z, 1, MPFR_RNDN);
1002 MPFR_ASSERTN(inex == 0);
1003 mpfr_div_2ui (z, z, e, MPFR_RNDN);
1004
1005 /* ensure last significant bit of z is 0 so that y-z is exact */
1006 odd = mpfr_min_prec (z) == p;
1007 if (odd) /* add one ulp to z */
1008 mpfr_nextabove (z);
1009
1010 /* compute x = y - z which should be exact, near 2+2^(-e) */
1011 inex = mpfr_sub (x, y, z, MPFR_RNDN);
1012 MPFR_ASSERTN(inex == 0);
1013 MPFR_ASSERTN(mpfr_get_exp (x) == 2);
1014
1015 /* restore initial z */
1016 if (odd)
1017 mpfr_nextbelow (z);
1018 mpfr_mul_2ui (z, z, e, MPFR_RNDN);
1019 inex = mpfr_add_ui (z, z, 1, MPFR_RNDN);
1020 MPFR_ASSERTN(inex == 0);
1021 mpfr_div_2ui (z, z, e, MPFR_RNDN);
1022 }
1023 mpfr_clears (x, y, z, (mpfr_ptr) 0);
1024 }
1025