diff options
Diffstat (limited to 'src/floatfns.c')
| -rw-r--r-- | src/floatfns.c | 46 |
1 files changed, 29 insertions, 17 deletions
diff --git a/src/floatfns.c b/src/floatfns.c index 1232fc0afa1..5c286772864 100644 --- a/src/floatfns.c +++ b/src/floatfns.c | |||
| @@ -491,27 +491,39 @@ DEFUN ("expt", Fexpt, Sexpt, 2, 2, 0, | |||
| 491 | y = XINT (arg2); | 491 | y = XINT (arg2); |
| 492 | acc = 1; | 492 | acc = 1; |
| 493 | 493 | ||
| 494 | if (y < 0) | 494 | if ((x == 0 && y != 0) || x == 1 || (x == -1 && (y & 1))) |
| 495 | { | 495 | return arg1; |
| 496 | if (x == 1) | 496 | if (x == -1) |
| 497 | acc = 1; | 497 | y = 0; |
| 498 | else if (x == -1) | 498 | |
| 499 | acc = (y & 1) ? -1 : 1; | 499 | while (1) |
| 500 | else | ||
| 501 | acc = 0; | ||
| 502 | } | ||
| 503 | else | ||
| 504 | { | 500 | { |
| 505 | while (y > 0) | 501 | if (y & 1) |
| 506 | { | 502 | { |
| 507 | if (y & 1) | 503 | if (x < 0 |
| 508 | acc *= x; | 504 | ? (acc < 0 |
| 509 | x *= x; | 505 | ? acc < MOST_POSITIVE_FIXNUM / x |
| 510 | y = (unsigned)y >> 1; | 506 | : MOST_NEGATIVE_FIXNUM / x < acc) |
| 507 | : (acc < 0 | ||
| 508 | ? acc < MOST_NEGATIVE_FIXNUM / x | ||
| 509 | : MOST_POSITIVE_FIXNUM / x < acc)) | ||
| 510 | break; | ||
| 511 | acc *= x; | ||
| 511 | } | 512 | } |
| 513 | |||
| 514 | y >>= 1; | ||
| 515 | if (y == 0) | ||
| 516 | { | ||
| 517 | XSETINT (val, acc); | ||
| 518 | return val; | ||
| 519 | } | ||
| 520 | |||
| 521 | if (x < 0 | ||
| 522 | ? x < MOST_POSITIVE_FIXNUM / x | ||
| 523 | : MOST_POSITIVE_FIXNUM / x < x) | ||
| 524 | break; | ||
| 525 | x *= x; | ||
| 512 | } | 526 | } |
| 513 | XSETINT (val, acc); | ||
| 514 | return val; | ||
| 515 | } | 527 | } |
| 516 | f1 = FLOATP (arg1) ? XFLOAT_DATA (arg1) : XINT (arg1); | 528 | f1 = FLOATP (arg1) ? XFLOAT_DATA (arg1) : XINT (arg1); |
| 517 | f2 = FLOATP (arg2) ? XFLOAT_DATA (arg2) : XINT (arg2); | 529 | f2 = FLOATP (arg2) ? XFLOAT_DATA (arg2) : XINT (arg2); |