diff options
Diffstat (limited to 'src/floatfns.c')
| -rw-r--r-- | src/floatfns.c | 26 |
1 files changed, 7 insertions, 19 deletions
diff --git a/src/floatfns.c b/src/floatfns.c index 305c78cae63..eaa1b32eb17 100644 --- a/src/floatfns.c +++ b/src/floatfns.c | |||
| @@ -484,31 +484,19 @@ DEFUN ("expt", Fexpt, Sexpt, 2, 2, 0, | |||
| 484 | && INTEGERP (arg2) /* don't promote, if both are ints, and */ | 484 | && INTEGERP (arg2) /* don't promote, if both are ints, and */ |
| 485 | && 0 <= XINT (arg2)) /* we are sure the result is not fractional */ | 485 | && 0 <= XINT (arg2)) /* we are sure the result is not fractional */ |
| 486 | { /* this can be improved by pre-calculating */ | 486 | { /* this can be improved by pre-calculating */ |
| 487 | EMACS_INT acc, x, y; /* some binary powers of x then accumulating */ | 487 | EMACS_INT y; /* some binary powers of x then accumulating */ |
| 488 | EMACS_UINT acc, x; /* Unsigned so that overflow is well defined. */ | ||
| 488 | Lisp_Object val; | 489 | Lisp_Object val; |
| 489 | 490 | ||
| 490 | x = XINT (arg1); | 491 | x = XINT (arg1); |
| 491 | y = XINT (arg2); | 492 | y = XINT (arg2); |
| 492 | acc = 1; | 493 | acc = (y & 1 ? x : 1); |
| 493 | 494 | ||
| 494 | if (y < 0) | 495 | while ((y >>= 1) != 0) |
| 495 | { | 496 | { |
| 496 | if (x == 1) | 497 | x *= x; |
| 497 | acc = 1; | 498 | if (y & 1) |
| 498 | else if (x == -1) | 499 | acc *= x; |
| 499 | acc = (y & 1) ? -1 : 1; | ||
| 500 | else | ||
| 501 | acc = 0; | ||
| 502 | } | ||
| 503 | else | ||
| 504 | { | ||
| 505 | while (y > 0) | ||
| 506 | { | ||
| 507 | if (y & 1) | ||
| 508 | acc *= x; | ||
| 509 | x *= x; | ||
| 510 | y >>= 1; | ||
| 511 | } | ||
| 512 | } | 500 | } |
| 513 | XSETINT (val, acc); | 501 | XSETINT (val, acc); |
| 514 | return val; | 502 | return val; |