# Commands covered: expr
#
# This file contains a collection of tests for one or more of the Tcl
# built-in commands. Sourcing this file into Tcl runs the tests and
# generates output for errors.  No output means no errors were found.
#
# Copyright (c) 1996-1997 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
# RCS: @(#) $Id: expr.test,v 1.9 2000/04/10 17:18:59 ericm Exp $

source [file dirname [info script]]/testing.tcl

# Jim Tcl may have no math functions, and may not have specific math functions
if {[catch {expr pow(1,0)}]} {
    testConstraint pow 0
} else {
    testConstraint pow 1
}

# Tests for exponentiation handling
test expr-23.1 {CompileExponentialExpr: just exponential expr} {expr 4**2} 16
test expr-23.2 {CompileExponentialExpr: just exponential expr} {expr 0xff**2} 65025
test expr-23.3 {CompileExponentialExpr: just exponential expr} {expr -1**2} 1
test expr-23.4 {CompileExponentialExpr: just exponential expr} {expr 18**07} 612220032
test expr-23.5 {CompileExponentialExpr: error in exponential expr} -body {
    expr x**3
} -returnCodes error -match glob -result *
test expr-23.6 {CompileExponentialExpr: simple expo exprs} {expr 0xff**0x3} 16581375
test expr-23.7 {CompileExponentialExpr: error compiling expo arm} -body {
    expr (-3-)**6
} -returnCodes error -match glob -result *
test expr-23.8 {CompileExponentialExpr: error compiling expo arm} -body {
    expr 2**x
} -returnCodes error -match glob -result *
test expr-23.9 {CompileExponentialExpr: runtime error} tcl {
    list [catch {expr {24.0**"xx"}} msg] $msg
} {1 {can't use non-numeric string as operand of "**"}}
test expr-23.10 {CompileExponentialExpr: runtime error} tcl {
    list [catch {expr {"a"**2}} msg] $msg
} {1 {can't use non-numeric string as operand of "**"}}
test expr-23.11 {CompileExponentialExpr: runtime error} {
    list [catch {expr {0**-1}} msg] $msg
} {1 {exponentiation of zero by negative power}}
test expr-23.12 {CompileExponentialExpr: runtime error} tcl {
    list [catch {expr {0.0**-1.0}} msg] $msg
} {1 {exponentiation of zero by negative power}}
test expr-23.13 {CompileExponentialExpr: runtime error} {
    list [catch {expr {wide(0)**wide(-1)}} msg] $msg
} {1 {exponentiation of zero by negative power}}
test expr-23.14 {INST_EXPON: special cases} {expr {0**1}} 0
test expr-23.15 {INST_EXPON: special cases} {expr {0**0}} 1
test expr-23.16 {INST_EXPON: special cases} {expr {-2**-1}} 0
test expr-23.17 {INST_EXPON: special cases} {expr {-2**0}} 1
test expr-23.18 {INST_EXPON: special cases} {expr {-1**1}} -1
test expr-23.19 {INST_EXPON: special cases} {expr {-1**0}} 1
test expr-23.20 {INST_EXPON: special cases} {expr {-1**2}} 1
test expr-23.21 {INST_EXPON: special cases} {expr {-1**-1}} -1
test expr-23.22 {INST_EXPON: special cases} {expr {1**1234567}} 1
test expr-23.23 {INST_EXPON: special cases} {expr {2**-2}} 0
test expr-23.24 {INST_EXPON: special cases} {expr {wide(0)**wide(1)}} 0
test expr-23.25 {INST_EXPON: special cases} {expr {wide(0)**wide(0)}} 1
test expr-23.26 {INST_EXPON: special cases} {expr {wide(-2)**wide(-1)}} 0
test expr-23.27 {INST_EXPON: special cases} {expr {wide(-2)**wide(0)}} 1
test expr-23.28 {INST_EXPON: special cases} {expr {wide(-1)**wide(1)}} -1
test expr-23.29 {INST_EXPON: special cases} {expr {wide(-1)**wide(0)}} 1
test expr-23.30 {INST_EXPON: special cases} {expr {wide(-1)**wide(2)}} 1
test expr-23.31 {INST_EXPON: special cases} {expr {wide(-1)**wide(-1)}} -1
test expr-23.32 {INST_EXPON: special cases} {expr {wide(1)**wide(1234567)}} 1
test expr-23.33 {INST_EXPON: special cases} {expr {wide(2)**wide(-2)}} 0
test expr-23.34 {INST_EXPON: special cases} {expr {2**0}} 1
test expr-23.35 {INST_EXPON: special cases} {expr {wide(2)**0}} 1
test expr-23.36 {INST_EXPON: big integer} {expr {10**17}} 1[string repeat 0 17]
test expr-23.37 {INST_EXPON: big integer} {expr {10**18}} 1[string repeat 0 18]
test expr-23.38 {INST_EXPON: big integer} tcl {expr {10**19}} 1[string repeat 0 19]
test expr-23.39 {INST_EXPON: big integer} tcl {
    expr 1[string repeat 0 30]**2
} 1[string repeat 0 60]
test expr-23.40 {INST_EXPON: overflow to big integer} {expr {(-10)**3}} -1000
test expr-23.41 {INST_EXPON: overflow to big integer} tcl {expr 2**64} [expr 1<<64]
test expr-23.42 {INST_EXPON: overflow to big integer} tcl {expr 4**32} [expr 1<<64]
test expr-23.43 {INST_EXPON: overflow to big integer} tcl {expr 16**16} [expr 1<<64]
test expr-23.44 {INST_EXPON: overflow to big integer} tcl {expr 256**8} [expr 1<<64]
test expr-23.45 {INST_EXPON: Bug 1555371} {expr 2**1} 2
test expr-23.46 {INST_EXPON: Bug 1561260} -constraints tcl -body {
    expr 5**28
} -match glob -result *5
test expr-23.47 {INST_EXPON: Bug 1561260} tcl {
    expr 2**32*5**32
} 1[string repeat 0 32]
test expr-23.48 {INST_EXPON: TIP 274: right assoc} {
expr 2**1**3
} 2
test expr-23.49 {INST_EXPON: optimize powers of 2} {
    set trouble {test powers of 2}
    for {set tval 0} {$tval <= 63} {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} pow {
    set trouble {test small int powers with 64-bit results}
    for {set exp 2} {$exp <= 16} {incr exp} {
	set base [expr {wide(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}
test expr-23.54.0 {INST_EXPON: Bug 2798543} {
    expr {3**9 == 3**65545}
} 0
test expr-23.54.1 {INST_EXPON: Bug 2798543} {
    expr {3**10 == 3**65546}
} 0
test expr-23.54.2 {INST_EXPON: Bug 2798543} {
    expr {3**11 == 3**65547}
} 0
test expr-23.54.3 {INST_EXPON: Bug 2798543} {
    expr {3**12 == 3**65548}
} 0
test expr-23.54.4 {INST_EXPON: Bug 2798543} {
    expr {3**13 == 3**65549}
} 0
test expr-23.54.5 {INST_EXPON: Bug 2798543} {
    expr {3**14 == 3**65550}
} 0
test expr-23.54.6 {INST_EXPON: Bug 2798543} {
    expr {3**15 == 3**65551}
} 0
test expr-23.54.7 {INST_EXPON: Bug 2798543} {
    expr {3**16 == 3**65552}
} 0
test expr-23.54.8 {INST_EXPON: Bug 2798543} {
    expr {3**17 == 3**65553}
} 0
test expr-23.54.9 {INST_EXPON: Bug 2798543} {
    expr {3**18 == 3**65554}
} 0
test expr-23.54.10 {INST_EXPON: Bug 2798543} {
    expr {3**19 == 3**65555}
} 0
test expr-23.54.11 {INST_EXPON: Bug 2798543} {
    expr {3**9 == 3**131081}
} 0
test expr-23.54.13 {INST_EXPON: Bug 2798543} {
    expr {(-3)**9 == (-3)**65545}
} 0
test expr-23.55.0 {INST_EXPON: Bug 2798543} {
    expr {4**9 == 4**65545}
} 0
test expr-23.55.1 {INST_EXPON: Bug 2798543} {
    expr {4**15 == 4**65551}
} 0
test expr-23.55.2 {INST_EXPON: Bug 2798543} {
    expr {4**9 == 4**131081}
} 0
test expr-23.55.4 {INST_EXPON: Bug 2798543} {
    expr {(-4)**9 == (-4)**65545}
} 0
test expr-23.56.0 {INST_EXPON: Bug 2798543} {
    expr {5**9 == 5**65545}
} 0
test expr-23.56.1 {INST_EXPON: Bug 2798543} {
    expr {5**13 == 5**65549}
} 0
test expr-23.56.2 {INST_EXPON: Bug 2798543} {
    expr {5**9 == 5**131081}
} 0
test expr-23.56.4 {INST_EXPON: Bug 2798543} {
    expr {(-5)**9 == (-5)**65545}
} 0
test expr-23.57.0 {INST_EXPON: Bug 2798543} {
    expr {6**9 == 6**65545}
} 0
test expr-23.57.1 {INST_EXPON: Bug 2798543} {
    expr {6**11 == 6**65547}
} 0
test expr-23.57.2 {INST_EXPON: Bug 2798543} {
    expr {6**9 == 6**131081}
} 0
test expr-23.57.4 {INST_EXPON: Bug 2798543} {
    expr {(-6)**9 == (-6)**65545}
} 0
test expr-23.58.0 {INST_EXPON: Bug 2798543} {
    expr {7**9 == 7**65545}
} 0
test expr-23.58.1 {INST_EXPON: Bug 2798543} {
    expr {7**11 == 7**65547}
} 0
test expr-23.58.2 {INST_EXPON: Bug 2798543} {
    expr {7**9 == 7**131081}
} 0
test expr-23.58.4 {INST_EXPON: Bug 2798543} {
    expr {(-7)**9 == (-7)**65545}
} 0
test expr-23.59.0 {INST_EXPON: Bug 2798543} {
    expr {8**9 == 8**65545}
} 0
test expr-23.59.1 {INST_EXPON: Bug 2798543} {
    expr {8**10 == 8**65546}
} 0
test expr-23.59.2 {INST_EXPON: Bug 2798543} {
    expr {8**9 == 8**131081}
} 0
test expr-23.59.4 {INST_EXPON: Bug 2798543} {
    expr {(-8)**9 == (-8)**65545}
} 0
test expr-23.60.0 {INST_EXPON: Bug 2798543} {
    expr {9**9 == 9**65545}
} 0
test expr-23.60.1 {INST_EXPON: Bug 2798543} {
    expr {9**9 == 9**131081}
} 0
test expr-23.60.3 {INST_EXPON: Bug 2798543} {
    expr {(-9)**9 == (-9)**65545}
} 0
test expr-23.61.0 {INST_EXPON: Bug 2798543} {
    expr {10**9 == 10**65545}
} 0
test expr-23.61.1 {INST_EXPON: Bug 2798543} {
    expr {10**9 == 10**131081}
} 0
test expr-23.61.3 {INST_EXPON: Bug 2798543} {
    expr {(-10)**9 == (-10)**65545}
} 0
test expr-23.62.0 {INST_EXPON: Bug 2798543} {
    expr {11**9 == 11**65545}
} 0
test expr-23.62.1 {INST_EXPON: Bug 2798543} {
    expr {11**9 == 11**131081}
} 0
test expr-23.62.3 {INST_EXPON: Bug 2798543} {
    expr {(-11)**9 == (-11)**65545}
} 0
test expr-23.63.0 {INST_EXPON: Bug 2798543} {
    expr {3**20 == 3**65556}
} 0
test expr-23.63.1 {INST_EXPON: Bug 2798543} {
    expr {3**39 == 3**65575}
} 0
test expr-23.63.2 {INST_EXPON: Bug 2798543} {
    expr {3**20 == 3**131092}
} 0
test expr-23.63.4 {INST_EXPON: Bug 2798543} {
    expr {(-3)**20 == (-3)**65556}
} 0
test expr-23.64.0 {INST_EXPON: Bug 2798543} {
    expr {4**17 == 4**65553}
} 0
test expr-23.64.1 {INST_EXPON: Bug 2798543} {
    expr {4**31 == 4**65567}
} 0
test expr-23.64.2 {INST_EXPON: Bug 2798543} {
    expr {4**17 == 4**131089}
} 0
test expr-23.64.4 {INST_EXPON: Bug 2798543} {
    expr {(-4)**17 == (-4)**65553}
} 0
test expr-23.65.0 {INST_EXPON: Bug 2798543} {
    expr {5**17 == 5**65553}
} 0
test expr-23.65.1 {INST_EXPON: Bug 2798543} {
    expr {5**27 == 5**65563}
} 0
test expr-23.65.2 {INST_EXPON: Bug 2798543} {
    expr {5**17 == 5**131089}
} 0
test expr-23.65.4 {INST_EXPON: Bug 2798543} {
    expr {(-5)**17 == (-5)**65553}
} 0
test expr-23.66.0 {INST_EXPON: Bug 2798543} {
    expr {6**17 == 6**65553}
} 0
test expr-23.66.1 {INST_EXPON: Bug 2798543} {
    expr {6**24 == 6**65560}
} 0
test expr-23.66.2 {INST_EXPON: Bug 2798543} {
    expr {6**17 == 6**131089}
} 0
test expr-23.66.4 {INST_EXPON: Bug 2798543} {
    expr {(-6)**17 == (-6)**65553}
} 0
test expr-23.67.0 {INST_EXPON: Bug 2798543} {
    expr {7**17 == 7**65553}
} 0
test expr-23.67.1 {INST_EXPON: Bug 2798543} {
    expr {7**22 == 7**65558}
} 0
test expr-23.67.2 {INST_EXPON: Bug 2798543} {
    expr {7**17 == 7**131089}
} 0
test expr-23.67.4 {INST_EXPON: Bug 2798543} {
    expr {(-7)**17 == (-7)**65553}
} 0
test expr-23.68.0 {INST_EXPON: Bug 2798543} {
    expr {8**17 == 8**65553}
} 0
test expr-23.68.1 {INST_EXPON: Bug 2798543} {
    expr {8**20 == 8**65556}
} 0
test expr-23.68.2 {INST_EXPON: Bug 2798543} {
    expr {8**17 == 8**131089}
} 0
test expr-23.68.4 {INST_EXPON: Bug 2798543} {
    expr {(-8)**17 == (-8)**65553}
} 0
test expr-23.69.0 {INST_EXPON: Bug 2798543} {
    expr {9**17 == 9**65553}
} 0
test expr-23.69.1 {INST_EXPON: Bug 2798543} {
    expr {9**19 == 9**65555}
} 0
test expr-23.69.2 {INST_EXPON: Bug 2798543} {
    expr {9**17 == 9**131089}
} 0
test expr-23.69.4 {INST_EXPON: Bug 2798543} {
    expr {(-9)**17 == (-9)**65553}
} 0
test expr-23.70.0 {INST_EXPON: Bug 2798543} {
    expr {10**17 == 10**65553}
} 0
test expr-23.70.1 {INST_EXPON: Bug 2798543} {
    expr {10**18 == 10**65554}
} 0
test expr-23.70.2 {INST_EXPON: Bug 2798543} {
    expr {10**17 == 10**131089}
} 0
test expr-23.70.4 {INST_EXPON: Bug 2798543} {
    expr {(-10)**17 == (-10)**65553}
} 0
test expr-23.71.0 {INST_EXPON: Bug 2798543} {
    expr {11**17 == 11**65553}
} 0
test expr-23.71.1 {INST_EXPON: Bug 2798543} {
    expr {11**18 == 11**65554}
} 0
test expr-23.71.2 {INST_EXPON: Bug 2798543} {
    expr {11**17 == 11**131089}
} 0
test expr-23.71.4 {INST_EXPON: Bug 2798543} {
    expr {(-11)**17 == (-11)**65553}
} 0
test expr-23.72.0 {INST_EXPON: Bug 2798543} {
    expr {12**17 == 12**65553}
} 0
test expr-23.72.1 {INST_EXPON: Bug 2798543} {
    expr {12**17 == 12**131089}
} 0
test expr-23.72.3 {INST_EXPON: Bug 2798543} {
    expr {(-12)**17 == (-12)**65553}
} 0
test expr-23.73.0 {INST_EXPON: Bug 2798543} {
    expr {13**17 == 13**65553}
} 0
test expr-23.73.1 {INST_EXPON: Bug 2798543} {
    expr {13**17 == 13**131089}
} 0
test expr-23.73.3 {INST_EXPON: Bug 2798543} {
    expr {(-13)**17 == (-13)**65553}
} 0
test expr-23.74.0 {INST_EXPON: Bug 2798543} {
    expr {14**17 == 14**65553}
} 0
test expr-23.74.1 {INST_EXPON: Bug 2798543} {
    expr {14**17 == 14**131089}
} 0
test expr-23.74.3 {INST_EXPON: Bug 2798543} {
    expr {(-14)**17 == (-14)**65553}
} 0

	
# Some compilers get this wrong; ensure that we work around it correctly
test expr-24.1 {expr edge cases; shifting} {expr int(5)>>32} 0
test expr-24.2 {expr edge cases; shifting} {expr int(5)>>63} 0
test expr-24.3 {expr edge cases; shifting} {expr wide(5)>>32} 0
test expr-24.4 {expr edge cases; shifting} {expr wide(5)>>63} 0
test expr-24.7 {expr edge cases; shifting} {expr wide(5)<<32} 21474836480
test expr-24.8 {expr edge cases; shifting} {expr wide(10<<63)} 0
test expr-24.9 {expr edge cases; shifting} {expr 5>>32} 0

testreport
