diff options
-rw-r--r-- | init.c | 1 | ||||
-rw-r--r-- | log.c | 12 | ||||
-rw-r--r-- | mpfr.h | 2 | ||||
-rw-r--r-- | mul.c | 14 | ||||
-rw-r--r-- | pow.c | 2 |
5 files changed, 22 insertions, 9 deletions
@@ -48,6 +48,7 @@ mpfr_init2 (x, p) exit (1); } MPFR_SIZE(x) = xsize; + MPFR_CLEAR_FLAGS(x); MPFR_SET_ZERO(x); /* initializes to zero */ MPFR_EXP(x) = 0; /* avoids uninitialized memory reads for zero */ } @@ -64,16 +64,22 @@ mpfr_log(r, a, rnd_mode) /* If a is NaN, the result is NaN */ if (MPFR_IS_NAN(a)) - { MPFR_SET_NAN(r); return 1; } + { MPFR_CLEAR_FLAGS(r); MPFR_SET_NAN(r); return 1; } if (MPFR_IS_ZERO(a)) { - MPFR_SET_INF(r); if (MPFR_SIGN(r) != -1) { MPFR_CHANGE_SIGN(r); } + MPFR_CLEAR_FLAGS(r); + MPFR_SET_INF(r); + if (MPFR_SIGN(r) != -1) { MPFR_CHANGE_SIGN(r); } + return 1; } if (MPFR_IS_INF(a)) { - MPFR_SET_INF(r); if (MPFR_SIGN(r) != 1) { MPFR_CHANGE_SIGN(r); } + MPFR_CLEAR_FLAGS(r); + MPFR_SET_INF(r); + if (MPFR_SIGN(r) != 1) { MPFR_CHANGE_SIGN(r); } + return 1; } /* Now we can clear the flags without damage even if r == a */ @@ -105,7 +105,7 @@ typedef union ieee_double_extract Ieee_double_extract; bit 30 of _mp_size is used for Nan flag, bit 29 of _mp_size is used for Inf flag, remaining bits are used to store the number of allocated limbs */ -#define MPFR_CLEAR_FLAGS(x) (((x) -> _mp_size &= ~(0x70000000))) +#define MPFR_CLEAR_FLAGS(x) (((x) -> _mp_size &= ~(3 << 29))) #define MPFR_IS_NAN(x) (((x)->_mp_size >> 30)&1) #define MPFR_SET_NAN(x) ((x)->_mp_size |= (1<<30)) #define MPFR_IS_INF(x) (((x)->_mp_size >> 29)&1) @@ -46,26 +46,30 @@ mpfr_mul(a, b, c, rnd_mode) TMP_DECL(marker); /* deal with NaN and zero */ - if (MPFR_IS_NAN(b) || MPFR_IS_NAN(c)) { MPFR_SET_NAN(a); return; } + if (MPFR_IS_NAN(b) || MPFR_IS_NAN(c)) + { MPFR_CLEAR_FLAGS(a); MPFR_SET_NAN(a); return; } if (MPFR_IS_INF(b)) { - if (!MPFR_NOTZERO(c)) { MPFR_SET_NAN(a); return; } + if (!MPFR_NOTZERO(c)) { MPFR_CLEAR_FLAGS(a); MPFR_SET_NAN(a); return; } else { if (MPFR_SIGN(a) != MPFR_SIGN(b) * MPFR_SIGN(c)) MPFR_CHANGE_SIGN(a); + MPFR_CLEAR_FLAGS(a); MPFR_SET_INF(a); return; } } else if (MPFR_IS_INF(c)) { - if (!MPFR_NOTZERO(b)) { MPFR_SET_NAN(a); return; } + if (!MPFR_NOTZERO(b)) { MPFR_CLEAR_FLAGS(a); MPFR_SET_NAN(a); return; } else { if (MPFR_SIGN(a) != MPFR_SIGN(b) * MPFR_SIGN(c)) MPFR_CHANGE_SIGN(a); - MPFR_SET_INF(a); return; + MPFR_CLEAR_FLAGS(a); MPFR_SET_INF(a); return; } } - if (!MPFR_NOTZERO(b) || !MPFR_NOTZERO(c)) { MPFR_SET_ZERO(a); return; } + + if (!MPFR_NOTZERO(b) || !MPFR_NOTZERO(c)) + { MPFR_CLEAR_FLAGS(a); MPFR_SET_ZERO(a); return; } sign_product = MPFR_SIGN(b) * MPFR_SIGN(c); @@ -41,12 +41,14 @@ mpfr_pow_ui (x, y, n, rnd) if (MPFR_IS_INF(y)) { + MPFR_CLEAR_FLAGS(x); if (n == 0) { MPFR_SET_NAN(x); return 0; } else if ((MPFR_SIGN(y) < 0 && (MPFR_SIGN(x) > 0 || n % 2 == 0)) || (MPFR_SIGN(y) > 0 && (MPFR_SIGN(x) < 0 && n % 2 == 1))) MPFR_CHANGE_SIGN(x); MPFR_SET_INF(x); return 0; } + if (MPFR_IS_NAN(y)) { MPFR_CLEAR_FLAGS(x); MPFR_SET_NAN(x); return 0; } MPFR_CLEAR_FLAGS(x); if (n==0) { mpfr_set_ui(x, 1, rnd); return 0; } |