summaryrefslogtreecommitdiffstats
path: root/generic/tclExecute.c
diff options
context:
space:
mode:
authorKevin B Kenny <kennykb@acm.org>2007-09-11 02:39:34 (GMT)
committerKevin B Kenny <kennykb@acm.org>2007-09-11 02:39:34 (GMT)
commitf8cf12e3304f75d9b47518935fcbeb8dc38a7c82 (patch)
treef3b1d3651b591f9394d9b0e4cad1a89cd75d4206 /generic/tclExecute.c
parent0d3e2f0116da21f2c52ef225148e17555d4be6ff (diff)
downloadtcl-f8cf12e3304f75d9b47518935fcbeb8dc38a7c82.zip
tcl-f8cf12e3304f75d9b47518935fcbeb8dc38a7c82.tar.gz
tcl-f8cf12e3304f75d9b47518935fcbeb8dc38a7c82.tar.bz2
* generic/tclExecute.c: Corrected an off-by-one error in the
setting of MaxBaseWide for certain powers. [Bug 1767293 - problem reported in comments when bug was reopened].
Diffstat (limited to 'generic/tclExecute.c')
-rw-r--r--generic/tclExecute.c28
1 files changed, 25 insertions, 3 deletions
diff --git a/generic/tclExecute.c b/generic/tclExecute.c
index 606d2d1..1d48e9c 100644
--- a/generic/tclExecute.c
+++ b/generic/tclExecute.c
@@ -12,7 +12,7 @@
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclExecute.c,v 1.333 2007/09/10 21:47:21 msofer Exp $
+ * RCS: @(#) $Id: tclExecute.c,v 1.334 2007/09/11 02:39:35 kennykb Exp $
*/
#include "tclInt.h"
@@ -621,7 +621,8 @@ InitByteCodeExecution(
* instruction tracing. */
{
#if (LONG_MAX > 0x7fffffff) || !defined(TCL_WIDE_INT_IS_LONG)
- int i;
+ int i, j;
+ Tcl_WideInt w, x;
#endif
#ifdef TCL_COMPILE_DEBUG
if (Tcl_LinkVar(interp, "tcl_traceExec", (char *) &tclTraceExec,
@@ -634,8 +635,29 @@ InitByteCodeExecution(
(ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
#endif /* TCL_COMPILE_STATS */
#if (LONG_MAX > 0x7fffffff) || !defined(TCL_WIDE_INT_IS_LONG)
+
+ /*
+ * Fill in a table of what base can be raised to powers 2, 3, ... 16
+ * without overflowing a Tcl_WideInt
+ */
for (i = 2; i <= 16; ++i) {
- MaxBaseWide[i-2] = (Tcl_WideInt) pow((double) LLONG_MAX, 1.0 / i);
+
+ /* Compute an initial guess in floating point */
+
+ w = (Tcl_WideInt) pow((double) LLONG_MAX, 1.0 / i) + 1;
+
+ /* Correct the guess if it's too high */
+
+ for (;;) {
+ x = LLONG_MAX;
+ for (j = 0; j < i; ++j) {
+ x /= w;
+ }
+ if (x == 1) break;
+ --w;
+ }
+
+ MaxBaseWide[i-2] = w;
}
#endif
}