aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert2011-05-03 01:52:13 -0700
committerPaul Eggert2011-05-03 01:52:13 -0700
commit4ed0cebda869315a9e729daa55c50a16e2a5cde1 (patch)
tree33bc70952903170e5ce98d27ff8880947a043c65 /src
parent7fc4768c45bce52d34f183eb4734d9f58745ea3d (diff)
downloademacs-4ed0cebda869315a9e729daa55c50a16e2a5cde1.tar.gz
emacs-4ed0cebda869315a9e729daa55c50a16e2a5cde1.zip
* floatfns.c (Fexpt): Likewise.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog1
-rw-r--r--src/floatfns.c46
2 files changed, 30 insertions, 17 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 435f90abad9..26b3af3225c 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -7,6 +7,7 @@
7 (arith_driver, Fadd1, Fsub1): Use floating point if the result is 7 (arith_driver, Fadd1, Fsub1): Use floating point if the result is
8 out of Emacs fixnum range. 8 out of Emacs fixnum range.
9 * bytecode.c (exec_byte_code): Likewise, for Bsub1, Badd1, Bnegate. 9 * bytecode.c (exec_byte_code): Likewise, for Bsub1, Badd1, Bnegate.
10 * floatfns.c (Fexpt): Likewise.
10 11
11 * callproc.c (Fcall_process): Use 'volatile' to avoid vfork clobbering. 12 * callproc.c (Fcall_process): Use 'volatile' to avoid vfork clobbering.
12 13
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);