aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Eggert2011-05-04 23:31:14 -0700
committerPaul Eggert2011-05-04 23:31:14 -0700
commitc717b32678affe3864f0d5024a9de514c950214d (patch)
tree5e682fb44780734c00be9a203499b7a8651e560c
parent852a74a59b12d505eba86a0aed46bfe8af7b9acf (diff)
downloademacs-c717b32678affe3864f0d5024a9de514c950214d.tar.gz
emacs-c717b32678affe3864f0d5024a9de514c950214d.zip
Revert to wraparound integer arithmetic, instead of going to float.
-rw-r--r--doc/lispref/ChangeLog3
-rw-r--r--doc/lispref/numbers.texi12
-rw-r--r--doc/lispref/objects.texi11
-rw-r--r--etc/ChangeLog5
-rw-r--r--etc/NEWS6
-rw-r--r--src/ChangeLog10
-rw-r--r--src/bytecode.c6
-rw-r--r--src/data.c126
-rw-r--r--src/floatfns.c46
9 files changed, 77 insertions, 148 deletions
diff --git a/doc/lispref/ChangeLog b/doc/lispref/ChangeLog
index bca76b8a23c..163de31f220 100644
--- a/doc/lispref/ChangeLog
+++ b/doc/lispref/ChangeLog
@@ -1,9 +1,6 @@
12011-05-03 Paul Eggert <eggert@cs.ucla.edu> 12011-05-03 Paul Eggert <eggert@cs.ucla.edu>
2 2
3 * numbers.texi (Integer Basics): Large integers are treated as floats. 3 * numbers.texi (Integer Basics): Large integers are treated as floats.
4 (Arithmetic Operations, Math Functions): Large integers go to
5 floats instead of wrapping around.
6 * objects.texi (Integer Type): Likewise. (Bug#8611)
7 4
82011-04-30 Lars Magne Ingebrigtsen <larsi@gnus.org> 52011-04-30 Lars Magne Ingebrigtsen <larsi@gnus.org>
9 6
diff --git a/doc/lispref/numbers.texi b/doc/lispref/numbers.texi
index ebf5660febe..2c73a03a26c 100644
--- a/doc/lispref/numbers.texi
+++ b/doc/lispref/numbers.texi
@@ -507,9 +507,9 @@ commonly used.
507 All of these functions except @code{%} return a floating point value 507 All of these functions except @code{%} return a floating point value
508if any argument is floating. 508if any argument is floating.
509 509
510 If integer arithmetic overflows, the resulting value is converted 510 It is important to note that in Emacs Lisp, arithmetic functions
511to floating point. Thus @code{(1+ 536870911)} may evaluate to 511do not check for overflow. Thus @code{(1+ 268435455)} may evaluate to
512536870912.0, depending on your hardware. 512@minus{}268435456, depending on your hardware.
513 513
514@defun 1+ number-or-marker 514@defun 1+ number-or-marker
515This function returns @var{number-or-marker} plus 1. 515This function returns @var{number-or-marker} plus 1.
@@ -826,7 +826,7 @@ On the other hand, shifting one place to the right looks like this:
826As the example illustrates, shifting one place to the right divides the 826As the example illustrates, shifting one place to the right divides the
827value of a positive integer by two, rounding downward. 827value of a positive integer by two, rounding downward.
828 828
829The function @code{lsh} does 829The function @code{lsh}, like all Emacs Lisp arithmetic functions, does
830not check for overflow, so shifting left can discard significant bits 830not check for overflow, so shifting left can discard significant bits
831and change the sign of the number. For example, left shifting 831and change the sign of the number. For example, left shifting
832536,870,911 produces @minus{}2 on a 30-bit machine: 832536,870,911 produces @minus{}2 on a 30-bit machine:
@@ -1169,8 +1169,8 @@ approximately.
1169 1169
1170@defun expt x y 1170@defun expt x y
1171This function returns @var{x} raised to power @var{y}. If both 1171This function returns @var{x} raised to power @var{y}. If both
1172arguments are integers and @var{y} is nonnegative, the result is an 1172arguments are integers and @var{y} is positive, the result is an
1173integer if it is in Emacs integer range. 1173integer; in this case, overflow causes truncation, so watch out.
1174@end defun 1174@end defun
1175 1175
1176@defun sqrt arg 1176@defun sqrt arg
diff --git a/doc/lispref/objects.texi b/doc/lispref/objects.texi
index 6dd7878e53b..c58d54f13fc 100644
--- a/doc/lispref/objects.texi
+++ b/doc/lispref/objects.texi
@@ -179,10 +179,10 @@ to
179@tex 179@tex
180@math{2^{29}-1}) 180@math{2^{29}-1})
181@end tex 181@end tex
182on most machines. (Some machines may provide a wider range.) 182on most machines. (Some machines may provide a wider range.) It is
183If integer arithmetic overflows, the resulting value is converted 183important to note that the Emacs Lisp arithmetic functions do not check
184+to floating point. Thus @code{(1+ 536870911)} may evaluate to 184for overflow. Thus @code{(1+ 536870911)} is @minus{}536870912 on most
185+536870912.0, depending on your hardware. 185machines.
186 186
187 The read syntax for integers is a sequence of (base ten) digits with an 187 The read syntax for integers is a sequence of (base ten) digits with an
188optional sign at the beginning and an optional period at the end. The 188optional sign at the beginning and an optional period at the end. The
@@ -195,8 +195,7 @@ leading @samp{+} or a final @samp{.}.
1951 ; @r{The integer 1.} 1951 ; @r{The integer 1.}
1961. ; @r{Also the integer 1.} 1961. ; @r{Also the integer 1.}
197+1 ; @r{Also the integer 1.} 197+1 ; @r{Also the integer 1.}
1981073741825 ; @r{The floating point number 1073741825.0,} 1981073741825 ; @r{Also the integer 1 on a 30-bit implementation.}
199 ; @r{on a 30-bit implementation.}
200@end group 199@end group
201@end example 200@end example
202 201
diff --git a/etc/ChangeLog b/etc/ChangeLog
index bba73855d6e..0eb21406105 100644
--- a/etc/ChangeLog
+++ b/etc/ChangeLog
@@ -1,8 +1,3 @@
12011-05-03 Paul Eggert <eggert@cs.ucla.edu>
2
3 * NEWS: Integer overflow now yields floating-point instead of
4 wrapping around. (Bug#8611)
5
62011-05-03 Leo Liu <sdl.web@gmail.com> 12011-05-03 Leo Liu <sdl.web@gmail.com>
7 2
8 * NEWS: Mention the new command isearch-yank-pop. 3 * NEWS: Mention the new command isearch-yank-pop.
diff --git a/etc/NEWS b/etc/NEWS
index 669c143ba7f..5094ecfc4fc 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -728,12 +728,6 @@ soap-inspect.el is an interactive inspector for SOAP WSDL structures.
728 728
729* Incompatible Lisp Changes in Emacs 24.1 729* Incompatible Lisp Changes in Emacs 24.1
730 730
731+++
732** Integer arithmetic overflow now yields the nearest floating-piont
733value rather than wrapping around. For example, on a 32-bit machine,
734(1+ 536870911) yields 536870912.0, instead of the -536870912 it
735yielded in Emacs 23.3, or the 0 it yielded in Emacs 23.1.
736
737--- 731---
738** `char-direction-table' and the associated function `char-direction' 732** `char-direction-table' and the associated function `char-direction'
739were deleted. They were buggy and inferior to the new support of 733were deleted. They were buggy and inferior to the new support of
diff --git a/src/ChangeLog b/src/ChangeLog
index ee2db310562..2b4f498a0b9 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -11,16 +11,6 @@
11 11
12 * term.c: Don't include <stdarg.h>, as <lisp.h> does that. 12 * term.c: Don't include <stdarg.h>, as <lisp.h> does that.
13 13
14 Arithmetic overflows now return float rather than wrapping around.
15 (Bug#8611).
16 * data.c: Include <intprops.h>.
17 (arith_driver): Use floating point if the accumulator would otherwise
18 go out of EMACS_INT range.
19 (arith_driver, Fadd1, Fsub1): Use floating point if the result is
20 out of Emacs fixnum range.
21 * bytecode.c (exec_byte_code): Likewise, for Bsub1, Badd1, Bnegate.
22 * floatfns.c (Fexpt): Likewise.
23
24 * callproc.c (Fcall_process): Use 'volatile' to avoid vfork clobbering. 14 * callproc.c (Fcall_process): Use 'volatile' to avoid vfork clobbering.
25 15
26 * process.c (Fformat_network_address): Fix typo: args2 -> *args2. 16 * process.c (Fformat_network_address): Fix typo: args2 -> *args2.
diff --git a/src/bytecode.c b/src/bytecode.c
index ce79b011bbb..c3cd3d43072 100644
--- a/src/bytecode.c
+++ b/src/bytecode.c
@@ -1186,7 +1186,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
1186 { 1186 {
1187 Lisp_Object v1; 1187 Lisp_Object v1;
1188 v1 = TOP; 1188 v1 = TOP;
1189 if (INTEGERP (v1) && MOST_NEGATIVE_FIXNUM < XINT (v1)) 1189 if (INTEGERP (v1))
1190 { 1190 {
1191 XSETINT (v1, XINT (v1) - 1); 1191 XSETINT (v1, XINT (v1) - 1);
1192 TOP = v1; 1192 TOP = v1;
@@ -1204,7 +1204,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
1204 { 1204 {
1205 Lisp_Object v1; 1205 Lisp_Object v1;
1206 v1 = TOP; 1206 v1 = TOP;
1207 if (INTEGERP (v1) && XINT (v1) < MOST_POSITIVE_FIXNUM) 1207 if (INTEGERP (v1))
1208 { 1208 {
1209 XSETINT (v1, XINT (v1) + 1); 1209 XSETINT (v1, XINT (v1) + 1);
1210 TOP = v1; 1210 TOP = v1;
@@ -1290,7 +1290,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
1290 { 1290 {
1291 Lisp_Object v1; 1291 Lisp_Object v1;
1292 v1 = TOP; 1292 v1 = TOP;
1293 if (INTEGERP (v1) && - MOST_POSITIVE_FIXNUM <= XINT (v1)) 1293 if (INTEGERP (v1))
1294 { 1294 {
1295 XSETINT (v1, - XINT (v1)); 1295 XSETINT (v1, - XINT (v1));
1296 TOP = v1; 1296 TOP = v1;
diff --git a/src/data.c b/src/data.c
index beff570d552..577ae777d89 100644
--- a/src/data.c
+++ b/src/data.c
@@ -22,9 +22,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
22#include <signal.h> 22#include <signal.h>
23#include <stdio.h> 23#include <stdio.h>
24#include <setjmp.h> 24#include <setjmp.h>
25
26#include <intprops.h>
27
28#include "lisp.h" 25#include "lisp.h"
29#include "puresize.h" 26#include "puresize.h"
30#include "character.h" 27#include "character.h"
@@ -2429,8 +2426,10 @@ static Lisp_Object float_arith_driver (double, size_t, enum arithop,
2429static Lisp_Object 2426static Lisp_Object
2430arith_driver (enum arithop code, size_t nargs, register Lisp_Object *args) 2427arith_driver (enum arithop code, size_t nargs, register Lisp_Object *args)
2431{ 2428{
2429 register Lisp_Object val;
2432 register size_t argnum; 2430 register size_t argnum;
2433 register EMACS_INT accum = 0; 2431 register EMACS_INT accum = 0;
2432 register EMACS_INT next;
2434 2433
2435 switch (SWITCH_ENUM_CAST (code)) 2434 switch (SWITCH_ENUM_CAST (code))
2436 { 2435 {
@@ -2452,89 +2451,58 @@ arith_driver (enum arithop code, size_t nargs, register Lisp_Object *args)
2452 2451
2453 for (argnum = 0; argnum < nargs; argnum++) 2452 for (argnum = 0; argnum < nargs; argnum++)
2454 { 2453 {
2455 EMACS_INT a = accum;
2456 int use_float = 0;
2457
2458 /* Using args[argnum] as argument to CHECK_NUMBER_... */ 2454 /* Using args[argnum] as argument to CHECK_NUMBER_... */
2459 Lisp_Object val = args[argnum]; 2455 val = args[argnum];
2460 CHECK_NUMBER_OR_FLOAT_COERCE_MARKER (val); 2456 CHECK_NUMBER_OR_FLOAT_COERCE_MARKER (val);
2461 args[argnum] = val;
2462 2457
2463 if (FLOATP (val)) 2458 if (FLOATP (val))
2464 use_float = 1; 2459 return float_arith_driver ((double) accum, argnum, code,
2465 else 2460 nargs, args);
2461 args[argnum] = val;
2462 next = XINT (args[argnum]);
2463 switch (SWITCH_ENUM_CAST (code))
2466 { 2464 {
2467 EMACS_INT next = XINT (val); 2465 case Aadd:
2468 switch (SWITCH_ENUM_CAST (code)) 2466 accum += next;
2467 break;
2468 case Asub:
2469 accum = argnum ? accum - next : nargs == 1 ? - next : next;
2470 break;
2471 case Amult:
2472 accum *= next;
2473 break;
2474 case Adiv:
2475 if (!argnum)
2476 accum = next;
2477 else
2469 { 2478 {
2470 case Aadd: 2479 if (next == 0)
2471 if (next < 0 2480 xsignal0 (Qarith_error);
2472 ? a < TYPE_MINIMUM (EMACS_INT) - next 2481 accum /= next;
2473 : TYPE_MAXIMUM (EMACS_INT) - next < a)
2474 use_float = 1;
2475 else
2476 a += next;
2477 break;
2478 case Asub:
2479 if (argnum == 0 && nargs != 1)
2480 a = next;
2481 else if (next < 0
2482 ? TYPE_MAXIMUM (EMACS_INT) + next < a
2483 : a < TYPE_MINIMUM (EMACS_INT) + next)
2484 use_float = 1;
2485 else
2486 a -= next;
2487 break;
2488 case Amult:
2489 if (next < 0
2490 ? (a < 0
2491 ? a < TYPE_MAXIMUM (EMACS_INT) / next
2492 : next != -1 && TYPE_MINIMUM (EMACS_INT) / next < a)
2493 : (next != 0
2494 && (a < 0
2495 ? a < TYPE_MINIMUM (EMACS_INT) / next
2496 : TYPE_MAXIMUM (EMACS_INT) / next < a)))
2497 use_float = 1;
2498 else
2499 a *= next;
2500 break;
2501 case Adiv:
2502 if (!argnum)
2503 a = next;
2504 else
2505 {
2506 if (next == 0)
2507 xsignal0 (Qarith_error);
2508 a /= next;
2509 }
2510 break;
2511 case Alogand:
2512 a &= next;
2513 break;
2514 case Alogior:
2515 a |= next;
2516 break;
2517 case Alogxor:
2518 a ^= next;
2519 break;
2520 case Amax:
2521 if (!argnum || a < next)
2522 a = next;
2523 break;
2524 case Amin:
2525 if (!argnum || next < a)
2526 a = next;
2527 break;
2528 } 2482 }
2483 break;
2484 case Alogand:
2485 accum &= next;
2486 break;
2487 case Alogior:
2488 accum |= next;
2489 break;
2490 case Alogxor:
2491 accum ^= next;
2492 break;
2493 case Amax:
2494 if (!argnum || next > accum)
2495 accum = next;
2496 break;
2497 case Amin:
2498 if (!argnum || next < accum)
2499 accum = next;
2500 break;
2529 } 2501 }
2530
2531 if (use_float)
2532 return float_arith_driver (accum, argnum, code, nargs, args);
2533
2534 accum = a;
2535 } 2502 }
2536 2503
2537 return make_fixnum_or_float (accum); 2504 XSETINT (val, accum);
2505 return val;
2538} 2506}
2539 2507
2540#undef isnan 2508#undef isnan
@@ -2809,8 +2777,7 @@ Markers are converted to integers. */)
2809 2777
2810 if (FLOATP (number)) 2778 if (FLOATP (number))
2811 return (make_float (1.0 + XFLOAT_DATA (number))); 2779 return (make_float (1.0 + XFLOAT_DATA (number)));
2812 if (XINT (number) + 1 == MOST_POSITIVE_FIXNUM + 1) 2780
2813 return make_float (XINT (number) + 1);
2814 XSETINT (number, XINT (number) + 1); 2781 XSETINT (number, XINT (number) + 1);
2815 return number; 2782 return number;
2816} 2783}
@@ -2824,8 +2791,7 @@ Markers are converted to integers. */)
2824 2791
2825 if (FLOATP (number)) 2792 if (FLOATP (number))
2826 return (make_float (-1.0 + XFLOAT_DATA (number))); 2793 return (make_float (-1.0 + XFLOAT_DATA (number)));
2827 if (XINT (number) - 1 == MOST_NEGATIVE_FIXNUM - 1) 2794
2828 return make_float (XINT (number) - 1);
2829 XSETINT (number, XINT (number) - 1); 2795 XSETINT (number, XINT (number) - 1);
2830 return number; 2796 return number;
2831} 2797}
diff --git a/src/floatfns.c b/src/floatfns.c
index 5c286772864..1232fc0afa1 100644
--- a/src/floatfns.c
+++ b/src/floatfns.c
@@ -491,39 +491,27 @@ 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 ((x == 0 && y != 0) || x == 1 || (x == -1 && (y & 1))) 494 if (y < 0)
495 return arg1;
496 if (x == -1)
497 y = 0;
498
499 while (1)
500 { 495 {
501 if (y & 1) 496 if (x == 1)
502 { 497 acc = 1;
503 if (x < 0 498 else if (x == -1)
504 ? (acc < 0 499 acc = (y & 1) ? -1 : 1;
505 ? acc < MOST_POSITIVE_FIXNUM / x 500 else
506 : MOST_NEGATIVE_FIXNUM / x < acc) 501 acc = 0;
507 : (acc < 0 502 }
508 ? acc < MOST_NEGATIVE_FIXNUM / x 503 else
509 : MOST_POSITIVE_FIXNUM / x < acc)) 504 {
510 break; 505 while (y > 0)
511 acc *= x;
512 }
513
514 y >>= 1;
515 if (y == 0)
516 { 506 {
517 XSETINT (val, acc); 507 if (y & 1)
518 return val; 508 acc *= x;
509 x *= x;
510 y = (unsigned)y >> 1;
519 } 511 }
520
521 if (x < 0
522 ? x < MOST_POSITIVE_FIXNUM / x
523 : MOST_POSITIVE_FIXNUM / x < x)
524 break;
525 x *= x;
526 } 512 }
513 XSETINT (val, acc);
514 return val;
527 } 515 }
528 f1 = FLOATP (arg1) ? XFLOAT_DATA (arg1) : XINT (arg1); 516 f1 = FLOATP (arg1) ? XFLOAT_DATA (arg1) : XINT (arg1);
529 f2 = FLOATP (arg2) ? XFLOAT_DATA (arg2) : XINT (arg2); 517 f2 = FLOATP (arg2) ? XFLOAT_DATA (arg2) : XINT (arg2);