summaryrefslogtreecommitdiff
path: root/src/floatfns.c
diff options
context:
space:
mode:
authorPaul Eggert <eggert@cs.ucla.edu>2018-08-17 12:37:57 -0700
committerPaul Eggert <eggert@cs.ucla.edu>2018-08-17 12:38:30 -0700
commit33002872364c69e2e6004fb981a8c975c3b38413 (patch)
tree4ca6644df8b2476d8013ad47eda1c13bfb0aeccc /src/floatfns.c
parent9189afc1a823703e1cef648538ac4b22182eb099 (diff)
downloademacs-33002872364c69e2e6004fb981a8c975c3b38413.tar.gz
Improve ‘abs’ performance
* src/floatfns.c (Fabs): Improve performance by not copying the argument if it would eql the result. As a minor detail, don't assume fixnums are two’s complement.
Diffstat (limited to 'src/floatfns.c')
-rw-r--r--src/floatfns.c47
1 files changed, 30 insertions, 17 deletions
diff --git a/src/floatfns.c b/src/floatfns.c
index bbf7df4db37..ea2eb1016b1 100644
--- a/src/floatfns.c
+++ b/src/floatfns.c
@@ -266,30 +266,43 @@ DEFUN ("sqrt", Fsqrt, Ssqrt, 1, 1, 0,
DEFUN ("abs", Fabs, Sabs, 1, 1, 0,
doc: /* Return the absolute value of ARG. */)
- (register Lisp_Object arg)
+ (Lisp_Object arg)
{
CHECK_NUMBER (arg);
- if (BIGNUMP (arg))
+ if (FIXNUMP (arg))
{
- mpz_t val;
- mpz_init (val);
- mpz_abs (val, XBIGNUM (arg)->value);
- arg = make_number (val);
- mpz_clear (val);
+ if (XFIXNUM (arg) < 0)
+ {
+ EMACS_INT absarg = -XFIXNUM (arg);
+ if (absarg <= MOST_POSITIVE_FIXNUM)
+ arg = make_fixnum (absarg);
+ else
+ {
+ mpz_t val;
+ mpz_init (val);
+ mpz_set_intmax (val, absarg);
+ arg = make_number (val);
+ mpz_clear (val);
+ }
+ }
}
- else if (FIXNUMP (arg) && XFIXNUM (arg) == MOST_NEGATIVE_FIXNUM)
+ else if (FLOATP (arg))
{
- mpz_t val;
- mpz_init (val);
- mpz_set_intmax (val, - MOST_NEGATIVE_FIXNUM);
- arg = make_number (val);
- mpz_clear (val);
+ if (signbit (XFLOAT_DATA (arg)))
+ arg = make_float (- XFLOAT_DATA (arg));
+ }
+ else
+ {
+ if (mpz_sgn (XBIGNUM (arg)->value) < 0)
+ {
+ mpz_t val;
+ mpz_init (val);
+ mpz_neg (val, XBIGNUM (arg)->value);
+ arg = make_number (val);
+ mpz_clear (val);
+ }
}
- else if (FLOATP (arg))
- arg = make_float (fabs (XFLOAT_DATA (arg)));
- else if (XFIXNUM (arg) < 0)
- XSETINT (arg, - XFIXNUM (arg));
return arg;
}