aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert2018-08-17 12:37:57 -0700
committerPaul Eggert2018-08-17 12:38:30 -0700
commit33002872364c69e2e6004fb981a8c975c3b38413 (patch)
tree4ca6644df8b2476d8013ad47eda1c13bfb0aeccc /src
parent9189afc1a823703e1cef648538ac4b22182eb099 (diff)
downloademacs-33002872364c69e2e6004fb981a8c975c3b38413.tar.gz
emacs-33002872364c69e2e6004fb981a8c975c3b38413.zip
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')
-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,
266 266
267DEFUN ("abs", Fabs, Sabs, 1, 1, 0, 267DEFUN ("abs", Fabs, Sabs, 1, 1, 0,
268 doc: /* Return the absolute value of ARG. */) 268 doc: /* Return the absolute value of ARG. */)
269 (register Lisp_Object arg) 269 (Lisp_Object arg)
270{ 270{
271 CHECK_NUMBER (arg); 271 CHECK_NUMBER (arg);
272 272
273 if (BIGNUMP (arg)) 273 if (FIXNUMP (arg))
274 { 274 {
275 mpz_t val; 275 if (XFIXNUM (arg) < 0)
276 mpz_init (val); 276 {
277 mpz_abs (val, XBIGNUM (arg)->value); 277 EMACS_INT absarg = -XFIXNUM (arg);
278 arg = make_number (val); 278 if (absarg <= MOST_POSITIVE_FIXNUM)
279 mpz_clear (val); 279 arg = make_fixnum (absarg);
280 else
281 {
282 mpz_t val;
283 mpz_init (val);
284 mpz_set_intmax (val, absarg);
285 arg = make_number (val);
286 mpz_clear (val);
287 }
288 }
280 } 289 }
281 else if (FIXNUMP (arg) && XFIXNUM (arg) == MOST_NEGATIVE_FIXNUM) 290 else if (FLOATP (arg))
282 { 291 {
283 mpz_t val; 292 if (signbit (XFLOAT_DATA (arg)))
284 mpz_init (val); 293 arg = make_float (- XFLOAT_DATA (arg));
285 mpz_set_intmax (val, - MOST_NEGATIVE_FIXNUM); 294 }
286 arg = make_number (val); 295 else
287 mpz_clear (val); 296 {
297 if (mpz_sgn (XBIGNUM (arg)->value) < 0)
298 {
299 mpz_t val;
300 mpz_init (val);
301 mpz_neg (val, XBIGNUM (arg)->value);
302 arg = make_number (val);
303 mpz_clear (val);
304 }
288 } 305 }
289 else if (FLOATP (arg))
290 arg = make_float (fabs (XFLOAT_DATA (arg)));
291 else if (XFIXNUM (arg) < 0)
292 XSETINT (arg, - XFIXNUM (arg));
293 306
294 return arg; 307 return arg;
295} 308}