Posted to tcl by kbk at Tue Sep 11 00:51:15 GMT 2007view pretty
Index: generic/tclExecute.c =================================================================== RCS file: /cvsroot/tcl/tcl/generic/tclExecute.c,v retrieving revision 1.333 diff -u -r1.333 tclExecute.c --- generic/tclExecute.c 10 Sep 2007 21:47:21 -0000 1.333 +++ generic/tclExecute.c 11 Sep 2007 00:50:27 -0000 @@ -621,7 +621,8 @@ * 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 @@ (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 }