diff options
author | Paul Eggert <eggert@cs.ucla.edu> | 2018-08-17 12:37:57 -0700 |
---|---|---|
committer | Paul Eggert <eggert@cs.ucla.edu> | 2018-08-17 12:38:30 -0700 |
commit | 33002872364c69e2e6004fb981a8c975c3b38413 (patch) | |
tree | 4ca6644df8b2476d8013ad47eda1c13bfb0aeccc /src/floatfns.c | |
parent | 9189afc1a823703e1cef648538ac4b22182eb099 (diff) | |
download | emacs-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.c | 47 |
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; } |