summaryrefslogtreecommitdiff
path: root/sub.c
diff options
context:
space:
mode:
authorpelissip <pelissip@280ebfd0-de03-0410-8827-d642c229c3f4>2003-10-28 16:31:13 +0000
committerpelissip <pelissip@280ebfd0-de03-0410-8827-d642c229c3f4>2003-10-28 16:31:13 +0000
commit117edf14c822a22cdd9c25689aeadc904a1a30d1 (patch)
treee39bd61cefc24cc6cfbc5b2b956e4fb36015d111 /sub.c
parent734c0a144b04e2cae4e67b394010e3f6e3cadecc (diff)
downloadmpfr-117edf14c822a22cdd9c25689aeadc904a1a30d1.tar.gz
Use of MPFR_UNLIKELY and MPFR_IS_SINGULAR for fast detection of special values (Nan, Inf or Zero).
Start to encapsulate the sign to be independant of the reprensation (Must be 1 or -1). git-svn-id: svn://scm.gforge.inria.fr/svn/mpfr/trunk@2525 280ebfd0-de03-0410-8827-d642c229c3f4
Diffstat (limited to 'sub.c')
-rw-r--r--sub.c101
1 files changed, 50 insertions, 51 deletions
diff --git a/sub.c b/sub.c
index bdf3b3c20..18e3563fa 100644
--- a/sub.c
+++ b/sub.c
@@ -28,61 +28,60 @@ MA 02111-1307, USA. */
int
mpfr_sub (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mp_rnd_t rnd_mode)
{
- if (MPFR_IS_NAN(b) || MPFR_IS_NAN(c))
+ if (MPFR_ARE_SINGULAR(b,c))
{
- MPFR_SET_NAN(a);
- MPFR_RET_NAN;
- }
-
- MPFR_CLEAR_NAN(a);
-
- if (MPFR_IS_INF(b))
- {
- if (!MPFR_IS_INF(c) || MPFR_SIGN(b) != MPFR_SIGN(c))
- {
- MPFR_SET_INF(a);
- MPFR_SET_SAME_SIGN(a, b);
- MPFR_RET(0); /* exact */
- }
+ if (MPFR_IS_NAN(b) || MPFR_IS_NAN(c))
+ {
+ MPFR_SET_NAN(a);
+ MPFR_RET_NAN;
+ }
+ MPFR_CLEAR_NAN(a);
+ if (MPFR_IS_INF(b))
+ {
+ if (!MPFR_IS_INF(c) || MPFR_SIGN(b) != MPFR_SIGN(c))
+ {
+ MPFR_SET_INF(a);
+ MPFR_SET_SAME_SIGN(a, b);
+ MPFR_RET(0); /* exact */
+ }
+ else
+ {
+ MPFR_SET_NAN(a);
+ MPFR_RET_NAN;
+ }
+ }
else
- {
- MPFR_SET_NAN(a);
- MPFR_RET_NAN;
- }
- }
- else
- if (MPFR_IS_INF(c))
- {
- MPFR_SET_INF(a);
- if (MPFR_SIGN(c) == MPFR_SIGN(a))
- MPFR_CHANGE_SIGN(a);
- MPFR_RET(0); /* exact */
- }
-
- MPFR_ASSERTN(MPFR_IS_FP(b) && MPFR_IS_FP(c));
-
- if (MPFR_IS_ZERO(b))
- {
+ if (MPFR_IS_INF(c))
+ {
+ MPFR_SET_INF(a);
+ if (MPFR_SIGN(c) == MPFR_SIGN(a))
+ MPFR_CHANGE_SIGN(a);
+ MPFR_RET(0); /* exact */
+ }
+ if (MPFR_IS_ZERO(b))
+ {
+ if (MPFR_IS_ZERO(c))
+ {
+ if (MPFR_SIGN(a) !=
+ (rnd_mode != GMP_RNDD ?
+ ((MPFR_SIGN(b) < 0 && MPFR_SIGN(c) > 0) ? -1 : 1) :
+ ((MPFR_SIGN(b) > 0 && MPFR_SIGN(c) < 0) ? 1 : -1)))
+ MPFR_CHANGE_SIGN(a);
+ MPFR_CLEAR_INF(a);
+ MPFR_SET_ZERO(a);
+ MPFR_RET(0); /* 0 - 0 is exact */
+ }
+ return mpfr_neg (a, c, rnd_mode);
+ }
if (MPFR_IS_ZERO(c))
- {
- if (MPFR_SIGN(a) !=
- (rnd_mode != GMP_RNDD ?
- ((MPFR_SIGN(b) < 0 && MPFR_SIGN(c) > 0) ? -1 : 1) :
- ((MPFR_SIGN(b) > 0 && MPFR_SIGN(c) < 0) ? 1 : -1)))
- MPFR_CHANGE_SIGN(a);
- MPFR_CLEAR_INF(a);
- MPFR_SET_ZERO(a);
- MPFR_RET(0); /* 0 - 0 is exact */
- }
- return mpfr_neg (a, c, rnd_mode);
+ {
+ return mpfr_set (a, b, rnd_mode);
+ }
+ /* Should never reach here */
+ MPFR_ASSERTN(1);
}
-
- if (MPFR_IS_ZERO(c))
- {
- return mpfr_set (a, b, rnd_mode);
- }
-
- MPFR_CLEAR_INF(a);
+ MPFR_CLEAR_FLAGS(a);
+ MPFR_ASSERTD(MPFR_IS_PURE_FP(b) && MPFR_IS_PURE_FP(c));
if (MPFR_SIGN(b) == MPFR_SIGN(c))
{ /* signs are equal, it's a real subtraction */