summaryrefslogtreecommitdiff
path: root/Build/source/libs/mpfr/mpfr-src/src/ubf.c
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/libs/mpfr/mpfr-src/src/ubf.c')
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/ubf.c252
1 files changed, 0 insertions, 252 deletions
diff --git a/Build/source/libs/mpfr/mpfr-src/src/ubf.c b/Build/source/libs/mpfr/mpfr-src/src/ubf.c
deleted file mode 100644
index 8b3ba066b7c..00000000000
--- a/Build/source/libs/mpfr/mpfr-src/src/ubf.c
+++ /dev/null
@@ -1,252 +0,0 @@
-/* Functions to work with unbounded floats (limited low-level interface).
-
-Copyright 2016-2020 Free Software Foundation, Inc.
-Contributed by the AriC and Caramba 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 3 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.LESSER. If not, see
-https://www.gnu.org/licenses/ or 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"
-
-/* Note: In MPFR math functions, even if UBF code is not called first,
- we may still need to handle special values NaN and infinities here.
- Indeed, for MAXR * MAXR + (-inf), even though this is a special case,
- the computation will also generate an overflow due to MAXR * MAXR,
- so that UBF code will be called anyway (except if special cases are
- detected and handled separately, but for polynomial, this should not
- be needed). */
-
-/* Get the exponent of a regular MPFR number or UBF as a mpz_t, which is
- initialized by this function. The flags are not changed. */
-static void
-mpfr_init_get_zexp (mpz_ptr ez, mpfr_srcptr x)
-{
- mpz_init (ez);
-
- if (MPFR_IS_UBF (x))
- mpz_set (ez, MPFR_ZEXP (x));
- else
- {
- mpfr_exp_t ex = MPFR_GET_EXP (x);
-
-#if _MPFR_EXP_FORMAT <= 3
- /* mpfr_exp_t fits in a long */
- mpz_set_si (ez, ex);
-#else
- mp_limb_t e_limb[MPFR_EXP_LIMB_SIZE];
- mpfr_t e;
- int inex;
- MPFR_SAVE_EXPO_DECL (expo);
-
- MPFR_TMP_INIT1 (e_limb, e, sizeof (mpfr_exp_t) * CHAR_BIT);
- MPFR_SAVE_EXPO_MARK (expo);
- MPFR_DBGRES (inex = mpfr_set_exp_t (e, ex, MPFR_RNDN));
- MPFR_ASSERTD (inex == 0);
- MPFR_DBGRES (inex = mpfr_get_z (ez, e, MPFR_RNDN));
- MPFR_ASSERTD (inex == 0);
- MPFR_SAVE_EXPO_FREE (expo);
-#endif
- }
-}
-
-/* Exact product. The number a is assumed to have enough allocated memory,
- where the trailing bits are regarded as being part of the input numbers
- (no reallocation is attempted and no check is performed as MPFR_TMP_INIT
- could have been used). The arguments b and c may actually be UBF numbers
- (mpfr_srcptr can be seen a bit like void *, but is stronger).
- This function does not change the flags, except in case of NaN. */
-void
-mpfr_ubf_mul_exact (mpfr_ubf_ptr a, mpfr_srcptr b, mpfr_srcptr c)
-{
- MPFR_LOG_FUNC
- (("b[%Pu]=%.*Rg c[%Pu]=%.*Rg",
- mpfr_get_prec (b), mpfr_log_prec, b,
- mpfr_get_prec (c), mpfr_log_prec, c),
- ("a[%Pu]=%.*Rg",
- mpfr_get_prec (a), mpfr_log_prec, a));
-
- MPFR_ASSERTD ((mpfr_ptr) a != b);
- MPFR_ASSERTD ((mpfr_ptr) a != c);
- MPFR_SIGN (a) = MPFR_MULT_SIGN (MPFR_SIGN (b), MPFR_SIGN (c));
-
- if (MPFR_ARE_SINGULAR (b, c))
- {
- if (MPFR_IS_NAN (b) || MPFR_IS_NAN (c))
- MPFR_SET_NAN (a);
- else if (MPFR_IS_INF (b))
- {
- if (MPFR_NOTZERO (c))
- MPFR_SET_INF (a);
- else
- MPFR_SET_NAN (a);
- }
- else if (MPFR_IS_INF (c))
- {
- if (!MPFR_IS_ZERO (b))
- MPFR_SET_INF (a);
- else
- MPFR_SET_NAN (a);
- }
- else
- {
- MPFR_ASSERTD (MPFR_IS_ZERO(b) || MPFR_IS_ZERO(c));
- MPFR_SET_ZERO (a);
- }
- }
- else
- {
- mpfr_exp_t e;
- mp_size_t bn, cn;
- mpfr_limb_ptr ap;
- mp_limb_t u, v;
- int m;
-
- /* Note about the code below: For the choice of the precision of
- * the result a, one could choose PREC(b) + PREC(c), instead of
- * taking whole limbs into account, but in most cases where one
- * would gain one limb, one would need to copy the significand
- * instead of a no-op (see the mul.c code).
- * But in the case MPFR_LIMB_MSB (u) == 0, if the result fits in
- * an-1 limbs, one could actually do
- * mpn_rshift (ap, ap, k, GMP_NUMB_BITS - 1)
- * instead of
- * mpn_lshift (ap, ap, k, 1)
- * to gain one limb (and reduce the precision), replacing a shift
- * by another one. Would this be interesting?
- */
-
- bn = MPFR_LIMB_SIZE (b);
- cn = MPFR_LIMB_SIZE (c);
-
- ap = MPFR_MANT (a);
-
- if (bn == 1 && cn == 1)
- {
- umul_ppmm (ap[1], ap[0], MPFR_MANT(b)[0], MPFR_MANT(c)[0]);
- if (ap[1] & MPFR_LIMB_HIGHBIT)
- m = 0;
- else
- {
- ap[1] = (ap[1] << 1) | (ap[0] >> (GMP_NUMB_BITS - 1));
- ap[0] = ap[0] << 1;
- m = 1;
- }
- }
- else
- {
- u = (bn >= cn) ?
- mpn_mul (ap, MPFR_MANT (b), bn, MPFR_MANT (c), cn) :
- mpn_mul (ap, MPFR_MANT (c), cn, MPFR_MANT (b), bn);
- if (MPFR_LIMB_MSB (u) == 0)
- {
- m = 1;
- MPFR_DBGRES (v = mpn_lshift (ap, ap, bn + cn, 1));
- MPFR_ASSERTD (v == 0);
- }
- else
- m = 0;
- }
-
- if (! MPFR_IS_UBF (b) && ! MPFR_IS_UBF (c) &&
- (e = MPFR_GET_EXP (b) + MPFR_GET_EXP (c) - m,
- MPFR_EXP_IN_RANGE (e)))
- {
- MPFR_SET_EXP (a, e);
- }
- else
- {
- mpz_t be, ce;
-
- mpz_init (MPFR_ZEXP (a));
-
- /* This may involve copies of mpz_t, but exponents should not be
- very large integers anyway. */
- mpfr_init_get_zexp (be, b);
- mpfr_init_get_zexp (ce, c);
- mpz_add (MPFR_ZEXP (a), be, ce);
- mpz_clear (be);
- mpz_clear (ce);
- mpz_sub_ui (MPFR_ZEXP (a), MPFR_ZEXP (a), m);
- MPFR_SET_UBF (a);
- }
- }
-}
-
-/* Compare the exponents of two numbers, which can be either MPFR numbers
- or UBF numbers. If both numbers can be MPFR numbers, it is better to
- use the MPFR_UBF_EXP_LESS_P wrapper macro, which is optimized for this
- common case. */
-int
-mpfr_ubf_exp_less_p (mpfr_srcptr x, mpfr_srcptr y)
-{
- mpz_t xe, ye;
- int c;
-
- mpfr_init_get_zexp (xe, x);
- mpfr_init_get_zexp (ye, y);
- c = mpz_cmp (xe, ye) < 0;
- mpz_clear (xe);
- mpz_clear (ye);
- return c;
-}
-
-/* Convert an mpz_t to an mpfr_exp_t, saturated to
- the interval [MPFR_EXP_MIN,MPFR_EXP_MAX]. */
-mpfr_exp_t
-mpfr_ubf_zexp2exp (mpz_ptr ez)
-{
- mp_size_t n;
- mpfr_eexp_t e;
- mpfr_t d;
- int inex;
- MPFR_SAVE_EXPO_DECL (expo);
-
- n = ABSIZ (ez); /* limb size of ez */
- if (n == 0)
- return 0;
-
- MPFR_SAVE_EXPO_MARK (expo);
- mpfr_init2 (d, n * GMP_NUMB_BITS);
- MPFR_DBGRES (inex = mpfr_set_z (d, ez, MPFR_RNDN));
- MPFR_ASSERTD (inex == 0);
- e = mpfr_get_exp_t (d, MPFR_RNDZ);
- mpfr_clear (d);
- MPFR_SAVE_EXPO_FREE (expo);
- if (MPFR_UNLIKELY (e < MPFR_EXP_MIN))
- return MPFR_EXP_MIN;
- if (MPFR_UNLIKELY (e > MPFR_EXP_MAX))
- return MPFR_EXP_MAX;
- return e;
-}
-
-/* Return the difference of the exponents of x and y, saturated to
- the interval [MPFR_EXP_MIN,MPFR_EXP_MAX]. */
-mpfr_exp_t
-mpfr_ubf_diff_exp (mpfr_srcptr x, mpfr_srcptr y)
-{
- mpz_t xe, ye;
- mpfr_exp_t e;
-
- mpfr_init_get_zexp (xe, x);
- mpfr_init_get_zexp (ye, y);
- mpz_sub (xe, xe, ye);
- mpz_clear (ye);
- e = mpfr_ubf_zexp2exp (xe);
- mpz_clear (xe);
- return e;
-}