Gentoo Archives: gentoo-commits

From: "Daniel Black (dragonheart)" <dragonheart@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] gentoo-x86 commit in dev-libs/mpfr/files/2.3.0: patch04
Date: Wed, 26 Dec 2007 23:19:31
Message-Id: E1J7fX0-0002ZF-9s@stork.gentoo.org
1 dragonheart 07/12/26 23:19:22
2
3 Added: patch04
4 Log:
5 added upstream patch
6 (Portage version: 2.1.3.19)
7
8 Revision Changes Path
9 1.1 dev-libs/mpfr/files/2.3.0/patch04
10
11 file : http://sources.gentoo.org/viewcvs.py/gentoo-x86/dev-libs/mpfr/files/2.3.0/patch04?rev=1.1&view=markup
12 plain: http://sources.gentoo.org/viewcvs.py/gentoo-x86/dev-libs/mpfr/files/2.3.0/patch04?rev=1.1&content-type=text/plain
13
14 Index: patch04
15 ===================================================================
16 diff -Naurd mpfr-2.3.0-a/PATCHES mpfr-2.3.0-b/PATCHES
17 --- mpfr-2.3.0-a/PATCHES 2007-10-23 03:03:12.000000000 +0000
18 +++ mpfr-2.3.0-b/PATCHES 2007-10-23 03:06:18.000000000 +0000
19 @@ -0,0 +1 @@
20 +mpfr_subnormalize
21 diff -Naurd mpfr-2.3.0-a/VERSION mpfr-2.3.0-b/VERSION
22 --- mpfr-2.3.0-a/VERSION 2007-10-05 12:21:06.000000000 +0000
23 +++ mpfr-2.3.0-b/VERSION 2007-10-23 03:05:51.000000000 +0000
24 @@ -1 +1 @@
25 -2.3.0-p3
26 +2.3.0-p4
27 diff -Naurd mpfr-2.3.0-a/mpfr.h mpfr-2.3.0-b/mpfr.h
28 --- mpfr-2.3.0-a/mpfr.h 2007-10-05 12:21:06.000000000 +0000
29 +++ mpfr-2.3.0-b/mpfr.h 2007-10-23 03:05:51.000000000 +0000
30 @@ -27,7 +27,7 @@
31 #define MPFR_VERSION_MAJOR 2
32 #define MPFR_VERSION_MINOR 3
33 #define MPFR_VERSION_PATCHLEVEL 0
34 -#define MPFR_VERSION_STRING "2.3.0-p3"
35 +#define MPFR_VERSION_STRING "2.3.0-p4"
36
37 /* Macros dealing with MPFR VERSION */
38 #define MPFR_VERSION_NUM(a,b,c) (((a) << 16L) | ((b) << 8) | (c))
39 diff -Naurd mpfr-2.3.0-a/mpfr.texi mpfr-2.3.0-b/mpfr.texi
40 --- mpfr-2.3.0-a/mpfr.texi 2007-08-29 10:18:11.000000000 +0000
41 +++ mpfr-2.3.0-b/mpfr.texi 2007-10-23 03:05:25.000000000 +0000
42 @@ -2038,7 +2038,8 @@
43 @var{rnd} and @var{t} must be the used rounding mode for computing @var{x}
44 and the returned ternary value when computing @var{x}.
45 The subnormal exponent range is from @code{emin} to @code{emin+PREC(x)-1}.
46 -This functions assumes that @code{emax-emin >= PREC(x)}.
47 +If the result cannot be represented in the current exponent range
48 +(due to a too small @code{emax}), the behavior is undefined.
49 Note that unlike most functions, the result is compared to the exact one,
50 not the input value @var{x}, i.e.@: the ternary value is propagated.
51 This is a preliminary interface.
52 diff -Naurd mpfr-2.3.0-a/subnormal.c mpfr-2.3.0-b/subnormal.c
53 --- mpfr-2.3.0-a/subnormal.c 2007-08-29 10:18:11.000000000 +0000
54 +++ mpfr-2.3.0-b/subnormal.c 2007-10-23 03:05:25.000000000 +0000
55 @@ -26,10 +26,10 @@
56 /* For GMP_RNDN, we can have a problem of double rounding.
57 In such a case, this table helps to conclude what to do (y positive):
58 Rounding Bit | Sticky Bit | inexact | Action | new inexact
59 - 0 | ? | ? | Trunc | sticky
60 - 1 | 0 | -1 | Trunc |
61 + 0 | ? | ? | Trunc | sticky
62 + 1 | 0 | 1 | Trunc |
63 1 | 0 | 0 | Trunc if even |
64 - 1 | 0 | 1 | AddOneUlp |
65 + 1 | 0 | -1 | AddOneUlp |
66 1 | 1 | ? | AddOneUlp |
67
68 For other rounding mode, there isn't such a problem.
69 @@ -41,8 +41,6 @@
70 {
71 int inexact = 0;
72
73 - MPFR_ASSERTD ((mpfr_uexp_t) __gmpfr_emax - __gmpfr_emin >= MPFR_PREC (y));
74 -
75 /* The subnormal exponent range are from:
76 mpfr_emin to mpfr_emin + MPFR_PREC(y) - 1 */
77 if (MPFR_LIKELY (MPFR_IS_SINGULAR (y)
78 @@ -69,23 +67,24 @@
79 and use the previous table to conclude. */
80 s = MPFR_LIMB_SIZE (y) - 1;
81 mant = MPFR_MANT (y) + s;
82 - rb = *mant & (MPFR_LIMB_HIGHBIT>>1);
83 + rb = *mant & (MPFR_LIMB_HIGHBIT >> 1);
84 if (rb == 0)
85 goto set_min;
86 - sb = *mant & ((MPFR_LIMB_HIGHBIT>>1)-1);
87 + sb = *mant & ((MPFR_LIMB_HIGHBIT >> 1) - 1);
88 while (sb == 0 && s-- != 0)
89 sb = *--mant;
90 if (sb != 0)
91 goto set_min_p1;
92 /* Rounding bit is 1 and sticky bit is 0.
93 We need to examine old inexact flag to conclude. */
94 - if (old_inexact * MPFR_SIGN (y) < 0)
95 + if ((old_inexact > 0 && MPFR_SIGN (y) > 0) ||
96 + (old_inexact < 0 && MPFR_SIGN (y) < 0))
97 goto set_min;
98 - /* If inexact != 0, return 0.1*2^emin+1.
99 + /* If inexact != 0, return 0.1*2^(emin+1).
100 Otherwise, rounding bit = 1, sticky bit = 0 and inexact = 0
101 - So we have 0.1100000000000000000000000*2^emin exactly!!!
102 - we choose to return 0.1*2^emin+1 which minimizes the relative
103 - error. */
104 + So we have 0.1100000000000000000000000*2^emin exactly.
105 + We return 0.1*2^(emin+1) according to the even-rounding
106 + rule on subnormals. */
107 goto set_min_p1;
108 }
109 else if (MPFR_IS_LIKE_RNDZ (rnd, MPFR_IS_NEG (y)))
110 @@ -97,7 +96,8 @@
111 else
112 {
113 set_min_p1:
114 - mpfr_setmin (y, __gmpfr_emin+1);
115 + /* Note: mpfr_setmin will abort if __gmpfr_emax == __gmpfr_emin. */
116 + mpfr_setmin (y, __gmpfr_emin + 1);
117 inexact = MPFR_SIGN (y);
118 }
119 }
120 @@ -120,15 +120,17 @@
121 MPFR_SET_EXP (dest, MPFR_GET_EXP (dest)+1));
122 if (MPFR_LIKELY (old_inexact != 0))
123 {
124 - if (MPFR_UNLIKELY(rnd==GMP_RNDN && (inexact == MPFR_EVEN_INEX
125 - || inexact == -MPFR_EVEN_INEX)))
126 + if (MPFR_UNLIKELY(rnd == GMP_RNDN && (inexact == MPFR_EVEN_INEX
127 + || inexact == -MPFR_EVEN_INEX)))
128 {
129 - if (old_inexact*inexact*MPFR_INT_SIGN (y) > 0)
130 + /* if both roundings are in the same direction, we have to go
131 + back in the other direction */
132 + if (SAME_SIGN (inexact, old_inexact))
133 {
134 - if (inexact < 0)
135 - mpfr_nexttoinf (dest);
136 - else
137 + if (SAME_SIGN (inexact, MPFR_INT_SIGN (y)))
138 mpfr_nexttozero (dest);
139 + else
140 + mpfr_nexttoinf (dest);
141 inexact = -inexact;
142 }
143 }
144 @@ -136,7 +138,8 @@
145 inexact = old_inexact;
146 }
147 old_inexact = mpfr_set (y, dest, rnd);
148 - MPFR_ASSERTD (old_inexact == 0);
149 + MPFR_ASSERTN (old_inexact == 0);
150 + MPFR_ASSERTN (MPFR_IS_PURE_FP (y));
151 mpfr_clear (dest);
152 }
153 return inexact;
154 diff -Naurd mpfr-2.3.0-a/tests/tsubnormal.c mpfr-2.3.0-b/tests/tsubnormal.c
155 --- mpfr-2.3.0-a/tests/tsubnormal.c 2007-08-29 10:18:09.000000000 +0000
156 +++ mpfr-2.3.0-b/tests/tsubnormal.c 2007-10-23 03:05:25.000000000 +0000
157 @@ -22,6 +22,7 @@
158
159 #include <stdio.h>
160 #include <stdlib.h>
161 +#include <limits.h>
162
163 #include "mpfr-test.h"
164
165 @@ -41,6 +42,8 @@
166 {"0.11001E-10", 0, GMP_RNDZ, "0.1E-10"},
167 {"0.11001E-10", 0, GMP_RNDU, "0.1E-9"},
168 {"0.11000E-10", 0, GMP_RNDN, "0.1E-9"},
169 + {"0.11000E-10", -1, GMP_RNDN, "0.1E-9"},
170 + {"0.11000E-10", 1, GMP_RNDN, "0.1E-10"},
171 {"0.11111E-8", 0, GMP_RNDN, "0.10E-7"},
172 {"0.10111E-8", 0, GMP_RNDN, "0.11E-8"},
173 {"0.11110E-8", -1, GMP_RNDN, "0.10E-7"},
174 @@ -51,7 +54,7 @@
175 check1 (void)
176 {
177 mpfr_t x;
178 - int i, j;
179 + int i, j, k, s, old_inex;
180
181 mpfr_set_default_prec (9);
182 mpfr_set_emin (-10);
183 @@ -59,20 +62,115 @@
184
185 mpfr_init (x);
186 for (i = 0; i < (sizeof (tab) / sizeof (tab[0])); i++)
187 - {
188 - mpfr_set_str (x, tab[i].in, 2, GMP_RNDN);
189 - j = mpfr_subnormalize (x, tab[i].i, tab[i].rnd);
190 - if (mpfr_cmp_str (x, tab[i].out, 2, GMP_RNDN) != 0)
191 + for (s = 0; s <= (tab[i].rnd == GMP_RNDN); s++)
192 + for (k = 0; k <= 1; k++)
193 {
194 - printf ("Error for i=%d\nFor:%s\nExpected:%s\nGot:",
195 - i, tab[i].in, tab[i].out);
196 - mpfr_dump (x);
197 - exit (1);
198 + mpfr_set_str (x, tab[i].in, 2, GMP_RNDN);
199 + old_inex = tab[i].i;
200 + if (s)
201 + {
202 + mpfr_neg (x, x, GMP_RNDN);
203 + old_inex = - old_inex;
204 + }
205 + if (k && old_inex)
206 + old_inex = old_inex < 0 ? INT_MIN : INT_MAX;
207 + j = mpfr_subnormalize (x, old_inex, tab[i].rnd);
208 + /* TODO: test j. */
209 + if (s)
210 + mpfr_neg (x, x, GMP_RNDN);
211 + if (mpfr_cmp_str (x, tab[i].out, 2, GMP_RNDN) != 0)
212 + {
213 + char *sgn = s ? "-" : "";
214 + printf ("Error for i = %d (old_inex = %d), k = %d, x = %s%s\n"
215 + "Expected: %s%s\nGot: ", i, old_inex, k,
216 + sgn, tab[i].in, sgn, tab[i].out);
217 + if (s)
218 + mpfr_neg (x, x, GMP_RNDN);
219 + mpfr_dump (x);
220 + exit (1);
221 + }
222 }
223 - }
224 mpfr_clear (x);
225 }
226
227 +/* bug found by Kevin P. Rauch on 22 Oct 2007 */
228 +static void
229 +check2 (void)
230 +{
231 + mpfr_t x, y, z;
232 + int tern;
233 +
234 + mpfr_init2 (x, 32);
235 + mpfr_init2 (y, 32);
236 + mpfr_init2 (z, 32);
237 +
238 + mpfr_set_ui (x, 0xC0000000U, GMP_RNDN);
239 + mpfr_neg (x, x, GMP_RNDN);
240 + mpfr_set_ui (y, 0xFFFFFFFEU, GMP_RNDN);
241 + mpfr_set_exp (x, 0);
242 + mpfr_set_exp (y, 0);
243 + mpfr_set_emin (-29);
244 +
245 + tern = mpfr_mul (z, x, y, GMP_RNDN);
246 + /* z = -0.BFFFFFFE, tern > 0 */
247 +
248 + tern = mpfr_subnormalize (z, tern, GMP_RNDN);
249 + /* z should be -0.75 */
250 + MPFR_ASSERTN (tern < 0 && mpfr_cmp_si_2exp (z, -3, -2) == 0);
251 +
252 + mpfr_clear (x);
253 + mpfr_clear (y);
254 + mpfr_clear (z);
255 +}
256 +
257 +/* bug found by Kevin P. Rauch on 22 Oct 2007 */
258 +static void
259 +check3 (void)
260 +{
261 + mpfr_t x, y, z;
262 + int tern;
263 +
264 + mpfr_init2 (x, 32);
265 + mpfr_init2 (y, 32);
266 + mpfr_init2 (z, 32);
267 +
268 + mpfr_set_ui (x, 0xBFFFFFFFU, GMP_RNDN); /* 3221225471/2^32 */
269 + mpfr_set_ui (y, 0x80000001U, GMP_RNDN); /* 2147483649/2^32 */
270 + mpfr_set_exp (x, 0);
271 + mpfr_set_exp (y, 0);
272 + mpfr_set_emin (-1);
273 +
274 + /* the exact product is 6917529028714823679/2^64, which is rounded to
275 + 3/8 = 0.375, which is smaller, thus tern < 0 */
276 + tern = mpfr_mul (z, x, y, GMP_RNDN);
277 + MPFR_ASSERTN (tern < 0 && mpfr_cmp_ui_2exp (z, 3, -3) == 0);
278 +
279 + tern = mpfr_subnormalize (z, tern, GMP_RNDN);
280 + /* since emin = -1, and EXP(z)=-1, z should be rounded to precision
281 + EXP(z)-emin+1 = 1, i.e., z should be a multiple of the smallest possible
282 + positive representable value with emin=-1, which is 1/4. The two
283 + possible values are 1/4 and 2/4, which are at equal distance of z.
284 + But since tern < 0, we should choose the largest value, i.e., 2/4. */
285 + MPFR_ASSERTN (tern > 0 && mpfr_cmp_ui_2exp (z, 1, -1) == 0);
286 +
287 + /* here is another test for the alternate case, where z was rounded up
288 + first, thus we have to round down */
289 + mpfr_set_str_binary (x, "0.11111111111010110101011011011011");
290 + mpfr_set_str_binary (y, "0.01100000000001111100000000001110");
291 + tern = mpfr_mul (z, x, y, GMP_RNDN);
292 + MPFR_ASSERTN (tern > 0 && mpfr_cmp_ui_2exp (z, 3, -3) == 0);
293 + tern = mpfr_subnormalize (z, tern, GMP_RNDN);
294 + MPFR_ASSERTN (tern < 0 && mpfr_cmp_ui_2exp (z, 1, -2) == 0);
295 +
296 + /* finally the case where z was exact, which we simulate here */
297 + mpfr_set_ui_2exp (z, 3, -3, GMP_RNDN);
298 + tern = mpfr_subnormalize (z, 0, GMP_RNDN);
299 + MPFR_ASSERTN (tern > 0 && mpfr_cmp_ui_2exp (z, 1, -1) == 0);
300 +
301 + mpfr_clear (x);
302 + mpfr_clear (y);
303 + mpfr_clear (z);
304 +}
305
306 int
307 main (int argc, char *argv[])
308 @@ -80,6 +178,8 @@
309 tests_start_mpfr ();
310
311 check1 ();
312 + check2 ();
313 + check3 ();
314
315 tests_end_mpfr ();
316 return 0;
317 diff -Naurd mpfr-2.3.0-a/version.c mpfr-2.3.0-b/version.c
318 --- mpfr-2.3.0-a/version.c 2007-10-05 12:21:06.000000000 +0000
319 +++ mpfr-2.3.0-b/version.c 2007-10-23 03:05:51.000000000 +0000
320 @@ -25,5 +25,5 @@
321 const char *
322 mpfr_get_version (void)
323 {
324 - return "2.3.0-p3";
325 + return "2.3.0-p4";
326 }
327
328
329
330 --
331 gentoo-commits@g.o mailing list