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 |