summaryrefslogtreecommitdiff
path: root/Build/source/libs/mpfr/mpfr-src/src/cache.c
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/libs/mpfr/mpfr-src/src/cache.c')
-rw-r--r--Build/source/libs/mpfr/mpfr-src/src/cache.c64
1 files changed, 35 insertions, 29 deletions
diff --git a/Build/source/libs/mpfr/mpfr-src/src/cache.c b/Build/source/libs/mpfr/mpfr-src/src/cache.c
index 3e0c83622ea..ece6cf0a06d 100644
--- a/Build/source/libs/mpfr/mpfr-src/src/cache.c
+++ b/Build/source/libs/mpfr/mpfr-src/src/cache.c
@@ -1,6 +1,6 @@
/* mpfr_cache -- cache interface for multiple-precision constants in MPFR.
-Copyright 2004-2019 Free Software Foundation, Inc.
+Copyright 2004-2020 Free Software Foundation, Inc.
Contributed by the AriC and Caramba projects, INRIA.
This file is part of the GNU MPFR Library.
@@ -56,8 +56,8 @@ mpfr_clear_cache (mpfr_cache_t cache)
int
mpfr_cache (mpfr_ptr dest, mpfr_cache_t cache, mpfr_rnd_t rnd)
{
- mpfr_prec_t prec = MPFR_PREC (dest);
- mpfr_prec_t pold;
+ mpfr_prec_t dprec = MPFR_PREC (dest);
+ mpfr_prec_t cprec; /* precision of the cache */
int inexact, sign;
MPFR_SAVE_EXPO_DECL (expo);
@@ -69,33 +69,37 @@ mpfr_cache (mpfr_ptr dest, mpfr_cache_t cache, mpfr_rnd_t rnd)
/* Get the cache in read-only mode */
MPFR_LOCK_READ(cache->lock);
/* Read the precision within the cache */
- pold = MPFR_PREC (cache->x);
- if (MPFR_UNLIKELY (prec > pold))
+ cprec = MPFR_PREC (cache->x);
+ if (MPFR_UNLIKELY (dprec > cprec))
{
/* Free the cache in read-only mode */
/* And get the cache in read-write mode */
MPFR_LOCK_READ2WRITE(cache->lock);
- /* Retest the precision once we get the lock.
- If there is no lock, there is no harm in this code */
- pold = MPFR_PREC (cache->x);
- if (MPFR_LIKELY (prec > pold))
+ /* Retest the precision once we get the lock (since it might have
+ changed). If there is no lock, there is no harm in this code. */
+ cprec = MPFR_PREC (cache->x);
+ if (MPFR_LIKELY (dprec > cprec))
{
- /* No previous result in the cache or the precision of the previous
- result is not sufficient. We increase the cache size by at least
- 10% to avoid invalidating the cache many times if one performs
- several computations with small increase of precision. */
- if (MPFR_UNLIKELY (pold == 0)) /* No previous result. */
- mpfr_init2 (cache->x, prec); /* as pold = prec below */
+ /* No previous result in the cache or the precision of the
+ previous result is not sufficient. */
+ if (MPFR_UNLIKELY (cprec == 0)) /* No previous result. */
+ {
+ cprec = dprec;
+ mpfr_init2 (cache->x, cprec);
+ }
else
- pold += pold / 10;
-
- /* Update the cache. */
- if (pold < prec)
- pold = prec;
+ {
+ /* We increase the cache size by at least 10% to avoid
+ invalidating the cache many times if one performs
+ several computations with small increase of precision. */
+ cprec += cprec / 10;
+ if (cprec < dprec)
+ cprec = dprec;
+ /* no need to keep the previous value */
+ mpfr_set_prec (cache->x, cprec);
+ }
- /* no need to keep the previous value */
- mpfr_set_prec (cache->x, pold);
cache->inexact = (*cache->func) (cache->x, MPFR_RNDN);
}
@@ -104,9 +108,9 @@ mpfr_cache (mpfr_ptr dest, mpfr_cache_t cache, mpfr_rnd_t rnd)
MPFR_LOCK_WRITE2READ(cache->lock);
}
- /* now pold >= prec is the precision of cache->x */
- MPFR_ASSERTD (pold >= prec);
- MPFR_ASSERTD (MPFR_PREC (cache->x) == pold);
+ /* now cprec >= dprec is the precision of cache->x */
+ MPFR_ASSERTD (cprec >= dprec);
+ MPFR_ASSERTD (MPFR_PREC (cache->x) == cprec);
/* First, check if the cache has the exact value (unlikely).
Else the exact value is between (assuming x=cache->x > 0):
@@ -120,9 +124,11 @@ mpfr_cache (mpfr_ptr dest, mpfr_cache_t cache, mpfr_rnd_t rnd)
MPFR_EXP (dest) = MPFR_GET_EXP (cache->x);
MPFR_SET_SIGN (dest, sign);
- /* round cache->x from precision pold down to precision prec */
+ /* round cache->x from precision cprec down to precision dprec;
+ since we are in extended exponent range, for the values considered
+ here, an overflow is not possible (and wouldn't make much sense). */
MPFR_RNDRAW_GEN (inexact, dest,
- MPFR_MANT (cache->x), pold, rnd, sign,
+ MPFR_MANT (cache->x), cprec, rnd, sign,
if (MPFR_UNLIKELY (cache->inexact == 0))
{
if ((_sp[0] & _ulp) == 0)
@@ -140,8 +146,8 @@ mpfr_cache (mpfr_ptr dest, mpfr_cache_t cache, mpfr_rnd_t rnd)
inexact = -sign;
goto trunc_doit;
},
- if (MPFR_UNLIKELY (++MPFR_EXP (dest) > __gmpfr_emax))
- mpfr_overflow (dest, rnd, sign);
+ MPFR_EXP (dest) ++;
+ MPFR_ASSERTD (MPFR_EXP (dest) <= __gmpfr_emax);
);
/* Rather a likely, this is a 100% success rate for