Index: gcc/mpfr/sum.c |
diff --git a/gcc/mpfr/sum.c b/gcc/mpfr/sum.c |
deleted file mode 100644 |
index 228c14565b29fc24de25383798b02645e489a482..0000000000000000000000000000000000000000 |
--- a/gcc/mpfr/sum.c |
+++ /dev/null |
@@ -1,312 +0,0 @@ |
-/* Sum -- efficiently sum a list of floating-point numbers |
- |
-Copyright 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. |
-Contributed by the Arenaire and Cacao projects, INRIA. |
- |
-This file is part of the GNU MPFR Library. |
- |
-The GNU MPFR Library is free software; you can redistribute it and/or modify |
-it under the terms of the GNU Lesser General Public License as published by |
-the Free Software Foundation; either version 2.1 of the License, or (at your |
-option) any later version. |
- |
-The GNU MPFR Library is distributed in the hope that it will be useful, but |
-WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY |
-or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public |
-License for more details. |
- |
-You should have received a copy of the GNU Lesser General Public License |
-along with the GNU MPFR Library; see the file COPYING.LIB. If not, write to |
-the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, |
-MA 02110-1301, USA. */ |
- |
-#define MPFR_NEED_LONGLONG_H |
-#include "mpfr-impl.h" |
- |
-/* I would really like to use "mpfr_srcptr const []" but the norm is buggy: |
- it doesn't automaticaly cast a "mpfr_ptr []" to "mpfr_srcptr const []" |
- if necessary. So the choice are: |
- mpfr_s ** : ok |
- mpfr_s *const* : ok |
- mpfr_s **const : ok |
- mpfr_s *const*const : ok |
- const mpfr_s *const* : no |
- const mpfr_s **const : no |
- const mpfr_s *const*const: no |
- VL: this is not a bug, but a feature. See the reason here: |
- http://c-faq.com/ansi/constmismatch.html |
-*/ |
-static void heap_sort (mpfr_srcptr *const, unsigned long, mpfr_srcptr *); |
-static void count_sort (mpfr_srcptr *const, unsigned long, mpfr_srcptr *, |
- mp_exp_t, mpfr_uexp_t); |
- |
-/* Either sort the tab in perm and returns 0 |
- Or returns 1 for +INF, -1 for -INF and 2 for NAN */ |
-int |
-mpfr_sum_sort (mpfr_srcptr *const tab, unsigned long n, mpfr_srcptr *perm) |
-{ |
- mp_exp_t min, max; |
- mpfr_uexp_t exp_num; |
- unsigned long i; |
- int sign_inf; |
- |
- sign_inf = 0; |
- min = MPFR_EMIN_MAX; |
- max = MPFR_EMAX_MIN; |
- for (i = 0; i < n; i++) |
- { |
- if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (tab[i]))) |
- { |
- if (MPFR_IS_NAN (tab[i])) |
- return 2; /* Return NAN code */ |
- else if (MPFR_IS_INF (tab[i])) |
- { |
- if (sign_inf == 0) /* No previous INF */ |
- sign_inf = MPFR_SIGN (tab[i]); |
- else if (sign_inf != MPFR_SIGN (tab[i])) |
- return 2; /* Return NAN */ |
- } |
- } |
- else |
- { |
- if (MPFR_GET_EXP (tab[i]) < min) |
- min = MPFR_GET_EXP(tab[i]); |
- if (MPFR_GET_EXP (tab[i]) > max) |
- max = MPFR_GET_EXP(tab[i]); |
- } |
- } |
- if (MPFR_UNLIKELY (sign_inf != 0)) |
- return sign_inf; |
- |
- exp_num = max - min + 1; |
- /* FIXME : better test */ |
- if (exp_num > n * MPFR_INT_CEIL_LOG2 (n)) |
- heap_sort (tab, n, perm); |
- else |
- count_sort (tab, n, perm, min, exp_num); |
- return 0; |
-} |
- |
-#define GET_EXP1(x) (MPFR_IS_ZERO (x) ? min : MPFR_GET_EXP (x)) |
-/* Performs a count sort of the entries */ |
-static void |
-count_sort (mpfr_srcptr *const tab, unsigned long n, |
- mpfr_srcptr *perm, mp_exp_t min, mpfr_uexp_t exp_num) |
-{ |
- unsigned long *account; |
- unsigned long target_rank, i; |
- MPFR_TMP_DECL(marker); |
- |
- /* Reserve a place for potential 0 (with EXP min-1) |
- If there is no zero, we only lose one unused entry */ |
- min--; |
- exp_num++; |
- |
- /* Performs a counting sort of the entries */ |
- MPFR_TMP_MARK (marker); |
- account = (unsigned long *) MPFR_TMP_ALLOC (exp_num * sizeof * account); |
- for (i = 0; i < exp_num; i++) |
- account[i] = 0; |
- for (i = 0; i < n; i++) |
- account[GET_EXP1 (tab[i]) - min]++; |
- for (i = exp_num - 1; i >= 1; i--) |
- account[i - 1] += account[i]; |
- for (i = 0; i < n; i++) |
- { |
- target_rank = --account[GET_EXP1 (tab[i]) - min]; |
- perm[target_rank] = tab[i]; |
- } |
- MPFR_TMP_FREE (marker); |
-} |
- |
- |
-#define GET_EXP2(x) (MPFR_IS_ZERO (x) ? MPFR_EMIN_MIN : MPFR_GET_EXP (x)) |
- |
-/* Performs a heap sort of the entries */ |
-static void |
-heap_sort (mpfr_srcptr *const tab, unsigned long n, mpfr_srcptr *perm) |
-{ |
- unsigned long dernier_traite; |
- unsigned long i, pere; |
- mpfr_srcptr tmp; |
- unsigned long fils_gauche, fils_droit, fils_indigne; |
- /* Reminder of a heap structure : |
- node(i) has for left son node(2i +1) and right son node(2i) |
- and father(node(i)) = node((i - 1) / 2) |
- */ |
- |
- /* initialize the permutation to identity */ |
- for (i = 0; i < n; i++) |
- perm[i] = tab[i]; |
- |
- /* insertion phase */ |
- for (dernier_traite = 1; dernier_traite < n; dernier_traite++) |
- { |
- i = dernier_traite; |
- while (i > 0) |
- { |
- pere = (i - 1) / 2; |
- if (GET_EXP2 (perm[pere]) > GET_EXP2 (perm[i])) |
- { |
- tmp = perm[pere]; |
- perm[pere] = perm[i]; |
- perm[i] = tmp; |
- i = pere; |
- } |
- else |
- break; |
- } |
- } |
- |
- /* extraction phase */ |
- for (dernier_traite = n - 1; dernier_traite > 0; dernier_traite--) |
- { |
- tmp = perm[0]; |
- perm[0] = perm[dernier_traite]; |
- perm[dernier_traite] = tmp; |
- |
- i = 0; |
- while (1) |
- { |
- fils_gauche = 2 * i + 1; |
- fils_droit = fils_gauche + 1; |
- if (fils_gauche < dernier_traite) |
- { |
- if (fils_droit < dernier_traite) |
- { |
- if (GET_EXP2(perm[fils_droit]) < GET_EXP2(perm[fils_gauche])) |
- fils_indigne = fils_droit; |
- else |
- fils_indigne = fils_gauche; |
- |
- if (GET_EXP2 (perm[i]) > GET_EXP2 (perm[fils_indigne])) |
- { |
- tmp = perm[i]; |
- perm[i] = perm[fils_indigne]; |
- perm[fils_indigne] = tmp; |
- i = fils_indigne; |
- } |
- else |
- break; |
- } |
- else /* on a un fils gauche, pas de fils droit */ |
- { |
- if (GET_EXP2 (perm[i]) > GET_EXP2 (perm[fils_gauche])) |
- { |
- tmp = perm[i]; |
- perm[i] = perm[fils_gauche]; |
- perm[fils_gauche] = tmp; |
- } |
- break; |
- } |
- } |
- else /* on n'a pas de fils */ |
- break; |
- } |
- } |
-} |
- |
- |
-/* Sum a list of float with order given by permutation perm, |
- * intermediate size set to F. |
- * Internal use function. |
- */ |
-static int |
-sum_once (mpfr_ptr ret, mpfr_srcptr *const tab, unsigned long n, mp_prec_t F) |
-{ |
- mpfr_t sum; |
- unsigned long i; |
- int error_trap; |
- |
- MPFR_ASSERTD (n >= 2); |
- |
- mpfr_init2 (sum, F); |
- error_trap = mpfr_set (sum, tab[0], GMP_RNDN); |
- for (i = 1; i < n - 1; i++) |
- { |
- MPFR_ASSERTD (!MPFR_IS_NAN (sum) && !MPFR_IS_INF (sum)); |
- error_trap |= mpfr_add (sum, sum, tab[i], GMP_RNDN); |
- } |
- error_trap |= mpfr_add (ret, sum, tab[n - 1], GMP_RNDN); |
- mpfr_clear (sum); |
- return error_trap; |
-} |
- |
-/* Sum a list of floating-point numbers. |
- * FIXME : add reference to Demmel-Hida's paper. |
- */ |
- |
-int |
-mpfr_sum (mpfr_ptr ret, mpfr_ptr *const tab_p, unsigned long n, mp_rnd_t rnd) |
-{ |
- mpfr_t cur_sum; |
- mp_prec_t prec; |
- mpfr_srcptr *perm, *const tab = (mpfr_srcptr *) tab_p; |
- int k, error_trap; |
- MPFR_ZIV_DECL (loop); |
- MPFR_SAVE_EXPO_DECL (expo); |
- MPFR_TMP_DECL (marker); |
- |
- if (MPFR_UNLIKELY (n <= 1)) |
- { |
- if (n < 1) |
- { |
- MPFR_SET_ZERO (ret); |
- MPFR_SET_POS (ret); |
- return 0; |
- } |
- else |
- return mpfr_set (ret, tab[0], rnd); |
- } |
- |
- /* Sort and treat special cases */ |
- MPFR_TMP_MARK (marker); |
- perm = (mpfr_srcptr *) MPFR_TMP_ALLOC (n * sizeof *perm); |
- error_trap = mpfr_sum_sort (tab, n, perm); |
- /* Check if there was a NAN or a INF */ |
- if (MPFR_UNLIKELY (error_trap != 0)) |
- { |
- MPFR_TMP_FREE (marker); |
- if (error_trap == 2) |
- { |
- MPFR_SET_NAN (ret); |
- MPFR_RET_NAN; |
- } |
- MPFR_SET_INF (ret); |
- MPFR_SET_SIGN (ret, error_trap); |
- MPFR_RET (0); |
- } |
- |
- /* Initial precision */ |
- prec = MAX (MPFR_PREC (tab[0]), MPFR_PREC (ret)); |
- k = MPFR_INT_CEIL_LOG2 (n) + 1; |
- prec += k + 2; |
- mpfr_init2 (cur_sum, prec); |
- |
- /* Ziv Loop */ |
- MPFR_SAVE_EXPO_MARK (expo); |
- MPFR_ZIV_INIT (loop, prec); |
- for (;;) |
- { |
- error_trap = sum_once (cur_sum, perm, n, prec + k); |
- if (MPFR_LIKELY (error_trap == 0 || |
- (!MPFR_IS_ZERO (cur_sum) && |
- mpfr_can_round (cur_sum, |
- MPFR_GET_EXP (cur_sum) - prec + 2, |
- GMP_RNDN, rnd, MPFR_PREC (ret))))) |
- break; |
- MPFR_ZIV_NEXT (loop, prec); |
- mpfr_set_prec (cur_sum, prec); |
- } |
- MPFR_ZIV_FREE (loop); |
- MPFR_TMP_FREE (marker); |
- |
- error_trap |= mpfr_set (ret, cur_sum, rnd); |
- mpfr_clear (cur_sum); |
- |
- MPFR_SAVE_EXPO_FREE (expo); |
- error_trap |= mpfr_check_range (ret, 0, rnd); |
- return error_trap; /* It doesn't return the ternary value */ |
-} |
- |
-/* __END__ */ |