Tcl Source Code

Artifact [3d3c1cf84f]
Login

Artifact 3d3c1cf84f76fdad0e749b6a92f0794e8d32a3a3:

Attachment "power.patch" to ticket [1767293fff] added by kennykb 2007-08-09 00:12:50.
? NSK1KENNYKB03
? win/autom4te.cache
Index: generic/tclExecute.c
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tclExecute.c,v
retrieving revision 1.309
diff -r1.309 tclExecute.c
434a435,566
>  * Auxiliary tables used to compute powers of small integers
>  */
> 
> #if (LONG_MAX == 0x7fffffff)
> 
> /* 
>  * Maximum base that, when raised to powers 2, 3, ... 8, fits in a 32-bit
>  * signed integer
>  */
> 
> static const long MaxBase32[7] = {46340, 1290, 215, 73, 35, 21, 14};
> 
> /* 
>  * Table giving 3, 4, ..., 11, raised to the powers 9, 10, ...,
>  * as far as they fit in a 32-bit signed integer.  Exp32Index[i] gives
>  * the starting index of powers of i+3; Exp32Value[i] gives the corresponding
>  * powers.
>  */
> 
> static const unsigned short Exp32Index[] = {
>     0, 11, 18, 23, 26, 29, 31, 32, 33
> };
> static const long Exp32Value[] = {
>     19683, 59049, 177147, 531441, 1594323, 4782969, 14348907, 43046721,
>     129140163, 387420489, 1162261467, 262144, 1048576, 4194304,
>     16777216, 67108864, 268435456, 1073741824, 1953125, 9765625,
>     48828125, 244140625, 1220703125, 10077696, 60466176, 362797056,
>     40353607, 282475249, 1977326743, 134217728, 1073741824, 387420489,
>     1000000000
> };
> 
> #endif /* LONG_MAX == 0x7fffffff -- 32 bit machine */
> 
> #if (LONG_MAX > 0x7fffffff) || !defined(TCL_WIDE_INT_IS_LONG)
> 
> /*
>  * Maximum base that, when raised to powers 2, 3, ..., 16, fits in a 
>  * Tcl_WideInt.
>  */
> 
> static Tcl_WideInt MaxBaseWide[15];
> 
> /* 
>  *Table giving 3, 4, ..., 13 raised to powers greater than 16 when the
>  * results fit in a 64-bit signed integer.
>  */
> 
> static const unsigned short Exp64Index[] = {
>     0, 23, 38, 49, 57, 63, 67, 70, 72, 74, 75, 76
> };
> static const Tcl_WideInt Exp64Value[] = {
>     (Tcl_WideInt)243*243*243*3*3,
>     (Tcl_WideInt)243*243*243*3*3*3,
>     (Tcl_WideInt)243*243*243*3*3*3*3,
>     (Tcl_WideInt)243*243*243*243,
>     (Tcl_WideInt)243*243*243*243*3,
>     (Tcl_WideInt)243*243*243*243*3*3,
>     (Tcl_WideInt)243*243*243*243*3*3*3,
>     (Tcl_WideInt)243*243*243*243*3*3*3*3,
>     (Tcl_WideInt)243*243*243*243*243,
>     (Tcl_WideInt)243*243*243*243*243*3,
>     (Tcl_WideInt)243*243*243*243*243*3*3,
>     (Tcl_WideInt)243*243*243*243*243*3*3*3,
>     (Tcl_WideInt)243*243*243*243*243*3*3*3*3,
>     (Tcl_WideInt)243*243*243*243*243*243,
>     (Tcl_WideInt)243*243*243*243*243*243*3,
>     (Tcl_WideInt)243*243*243*243*243*243*3*3,
>     (Tcl_WideInt)243*243*243*243*243*243*3*3*3,
>     (Tcl_WideInt)243*243*243*243*243*243*3*3*3*3,
>     (Tcl_WideInt)243*243*243*243*243*243*243,
>     (Tcl_WideInt)243*243*243*243*243*243*243*3,
>     (Tcl_WideInt)243*243*243*243*243*243*243*3*3,
>     (Tcl_WideInt)243*243*243*243*243*243*243*3*3*3,
>     (Tcl_WideInt)243*243*243*243*243*243*243*3*3*3*3,
>     (Tcl_WideInt)1024*1024*1024*4*4,
>     (Tcl_WideInt)1024*1024*1024*4*4*4,
>     (Tcl_WideInt)1024*1024*1024*4*4*4*4,
>     (Tcl_WideInt)1024*1024*1024*1024,
>     (Tcl_WideInt)1024*1024*1024*1024*4,
>     (Tcl_WideInt)1024*1024*1024*1024*4*4,
>     (Tcl_WideInt)1024*1024*1024*1024*4*4*4,
>     (Tcl_WideInt)1024*1024*1024*1024*4*4*4*4,
>     (Tcl_WideInt)1024*1024*1024*1024*1024,
>     (Tcl_WideInt)1024*1024*1024*1024*1024*4,
>     (Tcl_WideInt)1024*1024*1024*1024*1024*4*4,
>     (Tcl_WideInt)1024*1024*1024*1024*1024*4*4*4,
>     (Tcl_WideInt)1024*1024*1024*1024*1024*4*4*4*4,
>     (Tcl_WideInt)1024*1024*1024*1024*1024*1024,
>     (Tcl_WideInt)1024*1024*1024*1024*1024*1024*4,
>     (Tcl_WideInt)3125*3125*3125*5*5,
>     (Tcl_WideInt)3125*3125*3125*5*5*5,
>     (Tcl_WideInt)3125*3125*3125*5*5*5*5,
>     (Tcl_WideInt)3125*3125*3125*3125,
>     (Tcl_WideInt)3125*3125*3125*3125*5,
>     (Tcl_WideInt)3125*3125*3125*3125*5*5,
>     (Tcl_WideInt)3125*3125*3125*3125*5*5*5,
>     (Tcl_WideInt)3125*3125*3125*3125*5*5*5*5,
>     (Tcl_WideInt)3125*3125*3125*3125*3125,
>     (Tcl_WideInt)3125*3125*3125*3125*3125*5,
>     (Tcl_WideInt)3125*3125*3125*3125*3125*5*5,
>     (Tcl_WideInt)7776*7776*7776*6*6,
>     (Tcl_WideInt)7776*7776*7776*6*6*6,
>     (Tcl_WideInt)7776*7776*7776*6*6*6*6,
>     (Tcl_WideInt)7776*7776*7776*7776,
>     (Tcl_WideInt)7776*7776*7776*7776*6,
>     (Tcl_WideInt)7776*7776*7776*7776*6*6,
>     (Tcl_WideInt)7776*7776*7776*7776*6*6*6,
>     (Tcl_WideInt)7776*7776*7776*7776*6*6*6*6,
>     (Tcl_WideInt)16807*16807*16807*7*7,
>     (Tcl_WideInt)16807*16807*16807*7*7*7,
>     (Tcl_WideInt)16807*16807*16807*7*7*7*7,
>     (Tcl_WideInt)16807*16807*16807*16807,
>     (Tcl_WideInt)16807*16807*16807*16807*7,
>     (Tcl_WideInt)16807*16807*16807*16807*7*7,
>     (Tcl_WideInt)32768*32768*32768*8*8,
>     (Tcl_WideInt)32768*32768*32768*8*8*8,
>     (Tcl_WideInt)32768*32768*32768*8*8*8*8,
>     (Tcl_WideInt)32768*32768*32768*32768,
>     (Tcl_WideInt)59049*59049*59049*9*9,
>     (Tcl_WideInt)59049*59049*59049*9*9*9,
>     (Tcl_WideInt)59049*59049*59049*9*9*9*9,
>     (Tcl_WideInt)100000*100000*100000*10*10,
>     (Tcl_WideInt)100000*100000*100000*10*10*10,
>     (Tcl_WideInt)161051*161051*161051*11*11,
>     (Tcl_WideInt)161051*161051*161051*11*11*11,
>     (Tcl_WideInt)248832*248832*248832*12*12,
>     (Tcl_WideInt)371293*371293*371293*13*13
> };
> 
> #endif
> 
> /*
495a628
>     int i;
505a639,643
> #if (LONG_MAX > 0x7fffffff) || !defined(TCL_WIDE_INT_IS_LONG)
>     for (i = 2; i <= 16; ++i) {
> 	MaxBaseWide[i-2] = (Tcl_WideInt) pow((double) LLONG_MAX, 1.0 / i);
>     }
> #endif
5129c5267,5268
< 	    long l1, l2 = 0;
---
> 	    long l1 = 0, l2 = 0;
> 	    Tcl_WideInt w1;
5140a5280,5284
> 		} else if (l2 == 1) {
> 		    /*
> 		     * Anything to the first power is itself
> 		     */
> 		    NEXT_INST_F(1, 1, 0);
5142a5287
> 
5240c5385,5660
< 	    /* TODO: Perform those computations that fit in native types */
---
> 
> 	    if (type1 == TCL_NUMBER_LONG && type2 == TCL_NUMBER_LONG) {
> 		if (l1 == 2) {
> 		    /*
> 		     * Reduce small powers of 2 to shifts.
> 		     */
> 		    if (l2 < CHAR_BIT * sizeof(long) - 1) {		
> 			TRACE(("%s %s => ", O2S(valuePtr), O2S(value2Ptr)));
> 			TclNewLongObj(objResultPtr, (1L << l2));
> 			TRACE(("%s\n", O2S(objResultPtr)));
> 			NEXT_INST_F(1, 2, 1);
> 		    }
> #if !defined(TCL_WIDE_INT_IS_LONG)
> 		    if (l2 < CHAR_BIT * sizeof(Tcl_WideInt) - 1) {
> 			TRACE(("%s %s => ", O2S(valuePtr), O2S(value2Ptr)));
> 			objResultPtr
> 			    = Tcl_NewWideIntObj(((Tcl_WideInt) 1) << l2);
> 			TRACE(("%s\n", O2S(objResultPtr)));
> 			NEXT_INST_F(1, 2, 1);
> 		    }
> #endif
> 		}
> 		if (l1 == -2) {
> 		    int signum = oddExponent ? -1 : 1;
> 		    /*
> 		     * Reduce small powers of 2 to shifts.
> 		     */
> 		    if (l2 < CHAR_BIT * sizeof(long) - 1) {		
> 			TRACE(("%s %s => ", O2S(valuePtr), O2S(value2Ptr)));
> 			TclNewLongObj(objResultPtr, signum * (1L << l2));
> 			TRACE(("%s\n", O2S(objResultPtr)));
> 			NEXT_INST_F(1, 2, 1);
> 		    }
> #if !defined(TCL_WIDE_INT_IS_LONG)
> 		    if (l2 < CHAR_BIT * sizeof(Tcl_WideInt) - 1) {
> 			TRACE(("%s %s => ", O2S(valuePtr), O2S(value2Ptr)));
> 			objResultPtr
> 			    = Tcl_NewWideIntObj(signum *
> 						(((Tcl_WideInt) 1) << l2));
> 			TRACE(("%s\n", O2S(objResultPtr)));
> 			NEXT_INST_F(1, 2, 1);
> 		    }
> #endif
> 		}
> #if (LONG_MAX == 0x7fffffff)
> 		if (l2 <= 8 &&
> 		    l1 <= MaxBase32[l2-2] && l1 >= -MaxBase32[l2-2]) {
> 		    /*
> 		     * Small powers of 32-bit integers
> 		     */
> 		    long lResult = l1 * l1; /* b**2 */
> 		    switch (l2) {
> 		    case 2:
> 			break;
> 		    case 3:
> 			lResult *= l1; /* b**3 */
> 			break;
> 		    case 4:
> 			lResult *= lResult; /* b**4 */
> 			break;
> 		    case 5:
> 			lResult *= lResult; /* b**4 */
> 			lResult *= l1; /* b**5 */
> 			break;
> 		    case 6:
> 			lResult *= l1; /* b**3 */
> 			lResult *= lResult; /* b**6 */
> 			break;
> 		    case 7:
> 			lResult *= l1; /* b**3 */
> 			lResult *= lResult; /* b**6 */
> 			lResult *= l1; /* b**7 */
> 			break;
> 		    case 8:
> 			lResult *= lResult; /* b**4 */
> 			lResult *= lResult; /* b**8 */
> 			break;
> 		    }
> 		    TRACE(("%s %s => ", O2S(valuePtr), O2S(value2Ptr)));
> 		    if (Tcl_IsShared(valuePtr)) {
> 			TclNewLongObj(objResultPtr, lResult);
> 			TRACE(("%s\n", O2S(objResultPtr)));
> 			NEXT_INST_F(1, 2, 1);
> 		    }
> 		    Tcl_SetLongObj(valuePtr, lResult);
> 		    TRACE(("%s\n", O2S(valuePtr)));
> 		    NEXT_INST_F(1, 1, 0);
> 		}
> 		if (l1 >= 3
> 		    && l1 < (sizeof(Exp32Index)
> 			     / sizeof(unsigned short)) - 1) {
> 		    unsigned short base = Exp32Index[l1-3] + l2 - 9;
> 		    if (base < Exp32Index[l1-2]) {
> 			/*
> 			 * 32-bit number raised to intermediate power,
> 			 * done by table lookup
> 			 */
> 			TRACE(("%s %s => ", O2S(valuePtr), O2S(value2Ptr)));
> 			if (Tcl_IsShared(valuePtr)) {
> 			    TclNewLongObj(objResultPtr, Exp32Value[base]);
> 			    TRACE(("%s\n", O2S(objResultPtr)));
> 			    NEXT_INST_F(1, 2, 1);
> 			}
> 			Tcl_SetLongObj(valuePtr, Exp32Value[base]);
> 			TRACE(("%s\n", O2S(valuePtr)));
> 			NEXT_INST_F(1, 1, 0);
> 		    }
> 		}
> 		if (-l1 >= 3
> 		    && -l1 < (sizeof(Exp32Index)
> 			     / sizeof(unsigned short)) - 1) {
> 		    unsigned short base = Exp32Index[-l1-3] + l2 - 9;
> 		    if (base < Exp32Index[-l1-2]) {
> 			long lResult = (oddExponent) ? 
> 			    -Exp32Value[base] : Exp32Value[base];
> 			/*
> 			 * 32-bit number raised to intermediate power,
> 			 * done by table lookup
> 			 */
> 			TRACE(("%s %s => ", O2S(valuePtr), O2S(value2Ptr)));
> 			if (Tcl_IsShared(valuePtr)) {
> 			    TclNewLongObj(objResultPtr, lResult);
> 			    TRACE(("%s\n", O2S(objResultPtr)));
> 			    NEXT_INST_F(1, 2, 1);
> 			}
> 			Tcl_SetLongObj(valuePtr, lResult);
> 			TRACE(("%s\n", O2S(valuePtr)));
> 			NEXT_INST_F(1, 1, 0);
> 		    }
> 		}
> #endif
> 	    }
> 	    if (type1 == TCL_NUMBER_LONG) {
> 		w1 = l1;
> #ifndef NO_WIDE_TYPE
> 	    } else if (type1 == TCL_NUMBER_WIDE) {
> 		w1 = *((const Tcl_WideInt*) ptr1);
> #endif
> 	    } else {
> 		w1 = 0;
> 	    }
> #if (LONG_MAX > 0x7fffffff) || !defined(TCL_WIDE_INT_IS_LONG)
> 	    if (w1 != 0 && type2 == TCL_NUMBER_LONG
> 		&& l2 <= 16 
> 		&& w1 <= MaxBaseWide[l2-2] && w1 >= -MaxBaseWide[l2-2]) {
> 		/* 
> 		 * Small powers of integers whose result is wide 
> 		 */
> 		Tcl_WideInt wResult = w1 * w1; /* b**2 */
> 		switch (l2) {
> 		case 2:
> 		    break;
> 		case 3:
> 		    wResult *= l1; /* b**3 */
> 		    break;
> 		case 4:
> 		    wResult *= wResult; /* b**4 */
> 		    break;
> 		case 5:
> 		    wResult *= wResult; /* b**4 */
> 		    wResult *= w1; /* b**5 */
> 		    break;
> 		case 6:
> 		    wResult *= w1; /* b**3 */
> 		    wResult *= wResult; /* b**6 */
> 		    break;
> 		case 7:
> 		    wResult *= w1; /* b**3 */
> 		    wResult *= wResult; /* b**6 */
> 		    wResult *= w1; /* b**7 */
> 		    break;
> 		case 8:
> 		    wResult *= wResult; /* b**4 */
> 		    wResult *= wResult; /* b**8 */
> 		    break;
> 		case 9:
> 		    wResult *= wResult; /* b**4 */
> 		    wResult *= wResult; /* b**8 */
> 		    wResult *= w1; /* b**9 */
> 		    break;
> 		case 10:
> 		    wResult *= wResult; /* b**4 */
> 		    wResult *= w1; /* b**5 */
> 		    wResult *= wResult;	/* b**10 */
> 		    break;
> 		case 11:
> 		    wResult *= wResult; /* b**4 */
> 		    wResult *= w1; /* b**5 */
> 		    wResult *= wResult;	/* b**10 */
> 		    wResult *= w1; /* b**11 */
> 		    break;
> 		case 12:
> 		    wResult *= w1; /* b**3 */
> 		    wResult *= wResult; /* b**6 */
> 		    wResult *= wResult; /* b**12 */
> 		    break;
> 		case 13:
> 		    wResult *= w1; /* b**3 */
> 		    wResult *= wResult; /* b**6 */
> 		    wResult *= wResult; /* b**12 */
> 		    wResult *= w1; /* b**13 */
> 		    break;
> 		case 14:
> 		    wResult *= w1; /* b**3 */
> 		    wResult *= wResult; /* b**6 */
> 		    wResult *= w1; /* b**7 */
> 		    wResult *= wResult;	/* b**14 */
> 		    break;
> 		case 15:
> 		    wResult *= w1; /* b**3 */
> 		    wResult *= wResult; /* b**6 */
> 		    wResult *= w1; /* b**7 */
> 		    wResult *= wResult;	/* b**14 */
> 		    wResult *= w1; /* b**15 */
> 		    break;
> 		case 16:
> 		    wResult *= wResult; /* b**4 */
> 		    wResult *= wResult; /* b**8 */
> 		    wResult *= wResult; /* b**16 */
> 		    break;
> 
> 		}
> 		TRACE(("%s %s => ", O2S(valuePtr), O2S(value2Ptr)));
> 		objResultPtr = Tcl_NewWideIntObj(wResult);
> 		TRACE(("%s\n", O2S(objResultPtr)));
> 		NEXT_INST_F(1, 2, 1);
> 	    }
> 
> 	    /*
> 	     * Handle cases of powers > 16 that still fit in a 64-bit
> 	     * word by doing table lookup
> 	     */
> 	    if (w1 >= 3
> 		&& w1 < (sizeof(Exp64Index)
> 			 / sizeof(unsigned short)) - 1) {
> 		unsigned short base = Exp64Index[w1-3] + l2 - 17;
> 		if (base < Exp64Index[w1-2]) {
> 		    /*
> 		     * 64-bit number raised to intermediate power,
> 		     * done by table lookup
> 		     */
> 		    TRACE(("%s %s => ", O2S(valuePtr), O2S(value2Ptr)));
> 		    if (Tcl_IsShared(valuePtr)) {
> 			objResultPtr = Tcl_NewWideIntObj(Exp64Value[base]);
> 			TRACE(("%s\n", O2S(objResultPtr)));
> 			NEXT_INST_F(1, 2, 1);
> 		    }
> 		    Tcl_SetWideIntObj(valuePtr, Exp64Value[base]);
> 		    TRACE(("%s\n", O2S(valuePtr)));
> 		    NEXT_INST_F(1, 1, 0);
> 		}
> 	    }
> 	    if (-w1 >= 3
> 		&& -w1 < (sizeof(Exp64Index)
> 			  / sizeof(unsigned short)) - 1) {
> 		unsigned short base = Exp64Index[-w1-3] + l2 - 17;
> 		if (base < Exp64Index[-w1-2]) {
> 		    Tcl_WideInt wResult = (oddExponent) ? 
> 			-Exp64Value[base] : Exp64Value[base];
> 		    /*
> 		     * 64-bit number raised to intermediate power,
> 		     * done by table lookup
> 		     */
> 		    TRACE(("%s %s => ", O2S(valuePtr), O2S(value2Ptr)));
> 		    if (Tcl_IsShared(valuePtr)) {
> 			objResultPtr = Tcl_NewWideIntObj(wResult);
> 			TRACE(("%s\n", O2S(objResultPtr)));
> 			NEXT_INST_F(1, 2, 1);
> 		    }
> 		    Tcl_SetWideIntObj(valuePtr, wResult);
> 		    TRACE(("%s\n", O2S(valuePtr)));
> 		    NEXT_INST_F(1, 1, 0);
> 		}
> 	    }
> #endif
> 	    
Index: tests/expr.test
===================================================================
RCS file: /cvsroot/tcl/tcl/tests/expr.test,v
retrieving revision 1.67
diff -r1.67 expr.test
986c986,1106
< 
---
> test expr-23.49 {INST_EXPON: optimize powers of 2} {
>     set trouble {test powers of 2}
>     for {set tval 0} {$tval <= 66} {incr tval} {
> 	set is [expr {2 ** $tval}]
> 	set sb [expr {1 << $tval}]
> 	if {$is != $sb} {
> 	    append trouble \n "2**" $tval " is " $is " should be " $sb
> 	}
> 	if {$tval >= 1} {
> 	    set is [expr {-2 ** $tval}]
> 	    set sb [expr {1 << $tval}]
> 	    if {$tval & 1} {
> 		set sb [expr {-$sb}]
> 	    }
> 	    if {$is != $sb} {
> 		append trouble \n "-2**" $tval " is " $is " should be " $sb
> 	    }
> 	}
>     }
>     set trouble
> } {test powers of 2}
> test expr-23.50 {INST_EXPON: small powers of 32-bit integers} {
>     set trouble {test small powers of 32-bit ints}
>     for {set base 3} {$base <= 45} {incr base} {
> 	set sb $base
> 	set sbm [expr {-$base}]
> 	for {set expt 2} {$expt <= 8} {incr expt} {
> 	    set sb [expr {$sb * $base}]
> 	    set is [expr {$base ** $expt}]
> 	    if {$sb != $is} {
> 		append trouble \n $base ** $expt " is " $is " should be " $sb
> 	    }
> 	    set sbm [expr {-$sbm * $base}]
> 	    set ism [expr {(-$base) ** $expt}]
> 	    if {$sbm != $ism} {
> 		append trouble \n - $base ** $expt " is " $ism \
> 		    " should be " $sbm
> 	    }
> 	}
>     }
>     set trouble
> } {test small powers of 32-bit ints}
> test expr-23.51 {INST_EXPON: intermediate powers of 32-bit integers} {
>     set trouble {test intermediate powers of 32-bit ints}
>     for {set base 3} {$base <= 11} {incr base} {
> 	set sb [expr {$base ** 8}]
> 	set sbm $sb
> 	for {set expt 9} {$expt <= 21} {incr expt} {
> 	    set sb [expr {$sb * $base}]
> 	    set sbm [expr {$sbm * -$base}]
> 	    set is [expr {$base ** $expt}]
> 	    set ism [expr {-$base ** $expt}]
> 	    if {$sb != $is} {
> 		append trouble \n $base ** $expt " is " $is " should be " $sb
> 	    }
> 	    if {$sbm != $ism} {
> 		append trouble \n - $base ** $expt " is " $ism  \
> 		    " should be " $sbm
> 	    }
> 	}
>     }
>     set trouble
> } {test intermediate powers of 32-bit ints}
> test expr-23.52 {INST_EXPON: small integer powers with 64-bit results} {
>     set trouble {test small int powers with 64-bit results}
>     for {set exp 2} {$exp <= 16} {incr exp} {
> 	set base [expr {entier(pow(double(0x7fffffffffffffff),(1.0/$exp)))}]
> 	set sb 1
> 	set sbm 1
> 	for {set i 0} {$i < $exp} {incr i} {
> 	    set sb [expr {$sb * $base}]
> 	    set sbm [expr {$sbm * -$base}]
> 	}
> 	set is [expr {$base ** $exp}]
> 	set ism [expr {-$base ** $exp}]
> 	if {$sb != $is} {
> 	    append trouble \n $base ** $exp " is " $is " should be " $sb
> 	}
> 	if {$sbm != $ism} {
> 	    append trouble \n - $base ** $exp " is " $ism " should be " $sbm
> 	}
> 	incr base
> 	set sb 1
> 	set sbm 1
> 	for {set i 0} {$i < $exp} {incr i} {
> 	    set sb [expr {$sb * $base}]
> 	    set sbm [expr {$sbm * -$base}]
> 	}
> 	set is [expr {$base ** $exp}]
> 	set ism [expr {-$base ** $exp}]
> 	if {$sb != $is} {
> 	    append trouble \n $base ** $exp " is " $is " should be " $sb
> 	}
> 	if {$sbm != $ism} {
> 	    append trouble \n - $base ** $exp " is " $ism " should be " $sbm
> 	}
>     }
>     set trouble
> } {test small int powers with 64-bit results}
> test expr-23.53 {INST_EXPON: intermediate powers of 64-bit integers} {
>     set trouble {test intermediate powers of 64-bit ints}
>     for {set base 3} {$base <= 13} {incr base} {
> 	set sb [expr {$base ** 15}]
> 	set sbm [expr {-$sb}]
> 	for {set expt 16} {$expt <= 39} {incr expt} {
> 	    set sb [expr {$sb * $base}]
> 	    set sbm [expr {$sbm * -$base}]
> 	    set is [expr {$base ** $expt}]
> 	    set ism [expr {-$base ** $expt}]
> 	    if {$sb != $is} {
> 		append trouble \n $base ** $expt " is " $is " should be " $sb
> 	    }
> 	    if {$sbm != $ism} {
> 		append trouble \n - $base ** $expt " is " $ism  \
> 		    " should be " $sbm
> 	    }
> 	}
>     }
>     set trouble
> } {test intermediate powers of 64-bit ints}
>