OSDN Git Service

Please enter the commit message for your changes. Lines starting
[eos/base.git] / util / src / TclTk / tcl8.6.12 / tests / mathop.test
1 # Commands covered: ::tcl::mathop::...
2 #
3 # This file contains a collection of tests for one or more of the Tcl built-in
4 # commands. Sourcing this file into Tcl runs the tests and generates output
5 # for errors. No output means no errors were found.
6 #
7 # Copyright (c) 2006 Donal K. Fellows
8 # Copyright (c) 2006 Peter Spjuth
9 #
10 # See the file "license.terms" for information on usage and redistribution of
11 # this file, and for a DISCLAIMER OF ALL WARRANTIES.
12
13 if {"::tcltest" ni [namespace children]} {
14     package require tcltest 2.1
15     namespace import -force ::tcltest::*
16 }
17
18 # A namespace to test that operators are exported and that they
19 # work when imported
20 namespace eval ::testmathop2 {
21     namespace import ::tcl::mathop::*
22 }
23
24 # Helper to test math ops.
25 # Test different invokation variants and see that they do the same thing.
26 # Byte compiled / non byte compiled version
27 # Shared / unshared arguments
28 # Original / imported
29 proc TestOp {op args} {
30     set results {}
31
32     # Non byte compiled version, shared args
33     if {[catch {::tcl::mathop::$op {*}$args} res]} {
34         append res " $::errorCode"
35     }
36     lappend results $res
37
38     # Non byte compiled version, unshared args
39     set cmd ::tcl::mathop::\$op
40     foreach arg $args {
41         append cmd " \[format %s [list $arg]\]"
42     }
43     if {[catch $cmd res]} {
44         append res " $::errorCode"
45     }
46     lappend results $res
47
48     # Non byte compiled imported
49     if {[catch {::testmathop2::$op {*}$args} res]} {
50         append res " $::errorCode"
51     }
52     lappend results [string map {testmathop2 tcl::mathop} $res]
53
54     # BC version
55     set argList1 {}
56     set argList2 {}
57     set argList3 {}
58     for {set t 0} {$t < [llength $args]} {incr t} {
59         lappend argList1 a$t
60         lappend argList2 \$a$t
61         lappend argList3 "\[format %s \$a$t\]"
62     }
63     # Shared args
64     proc _TestOp  $argList1 "::tcl::mathop::$op [join $argList2]"
65     # Unshared args
66     proc _TestOp2 $argList1 "::tcl::mathop::$op [join $argList3]"
67     # Imported
68     proc _TestOp3 $argList1 "::testmathop2::$op [join $argList2]"
69
70     set ::tcl_traceCompile 0  ;# Set to 2 to help with debug
71     if {[catch {_TestOp {*}$args} res]} {
72         append res " $::errorCode"
73     }
74     set ::tcl_traceCompile 0
75     lappend results $res
76
77     if {[catch {_TestOp2 {*}$args} res]} {
78         append res " $::errorCode"
79     }
80     lappend results $res
81
82     if {[catch {_TestOp3 {*}$args} res]} {
83         append res " $::errorCode"
84     }
85     lappend results [string map {testmathop2 tcl::mathop} $res]
86
87     # Check that they do the same
88     set len [llength $results]
89     for {set i 0} {$i < ($len - 1)} {incr i} {
90         set res1 [lindex $results $i]
91         set res2 [lindex $results $i+1]
92         if {$res1 ne $res2} {
93             return "$i:($res1 != $res2)"
94         }
95     }
96     return [lindex $results 0]
97 }
98
99 # start of tests
100
101 namespace eval ::testmathop {
102     namespace path ::tcl::mathop
103     variable op ;# stop surprises!
104
105     test mathop-1.1 {compiled +} { + } 0
106     test mathop-1.2 {compiled +} { + 1 } 1
107     test mathop-1.3 {compiled +} { + 1 2 } 3
108     test mathop-1.4 {compiled +} { + 1 2 3 } 6
109     test mathop-1.5 {compiled +} { + 1.0 2 3 } 6.0
110     test mathop-1.6 {compiled +} { + 1 2 3.0 } 6.0
111     test mathop-1.7 {compiled +} { + 100000000000 2 3 } 100000000005
112     test mathop-1.8 {compiled +} { + 1 2 300000000000 } 300000000003
113     test mathop-1.9 {compiled +} { + 1000000000000000000000 2 3 } 1000000000000000000005
114     test mathop-1.10 {compiled +} { + 1 2 3000000000000000000000 } 3000000000000000000003
115     test mathop-1.11 {compiled +: errors} -returnCodes error -body {
116         + x 0
117     } -result {can't use non-numeric string as operand of "+"}
118     test mathop-1.12 {compiled +: errors} -returnCodes error -body {
119         + nan 0
120     } -result {can't use non-numeric floating-point value as operand of "+"}
121     test mathop-1.13 {compiled +: errors} -returnCodes error -body {
122         + 0 x
123     } -result {can't use non-numeric string as operand of "+"}
124     test mathop-1.14 {compiled +: errors} -returnCodes error -body {
125         + 0 nan
126     } -result {can't use non-numeric floating-point value as operand of "+"}
127     test mathop-1.15 {compiled +: errors} -returnCodes error -body {
128         + 0o8 0
129     } -result {can't use invalid octal number as operand of "+"}
130     test mathop-1.16 {compiled +: errors} -returnCodes error -body {
131         + 0 0o8
132     } -result {can't use invalid octal number as operand of "+"}
133     test mathop-1.17 {compiled +: errors} -returnCodes error -body {
134         + 0 [error expectedError]
135     } -result expectedError
136     test mathop-1.18 {compiled +: argument processing order} -body {
137         # Bytecode compilation known hard for 3+ arguments
138         list [catch {
139             + [set x 0] [incr x] NaN [incr x] [error expected] [incr x]
140         } msg] $msg $x
141     } -result {1 expected 2}
142     set op +
143     test mathop-1.19 {interpreted +} { $op } 0
144     test mathop-1.20 {interpreted +} { $op 1 } 1
145     test mathop-1.21 {interpreted +} { $op 1 2 } 3
146     test mathop-1.22 {interpreted +} { $op 1 2 3 } 6
147     test mathop-1.23 {interpreted +} { $op 1.0 2 3 } 6.0
148     test mathop-1.24 {interpreted +} { $op 1 2 3.0 } 6.0
149     test mathop-1.25 {interpreted +} { $op 100000000000 2 3 } 100000000005
150     test mathop-1.26 {interpreted +} { $op 1 2 300000000000 } 300000000003
151     test mathop-1.27 {interpreted +} { $op 1000000000000000000000 2 3 } 1000000000000000000005
152     test mathop-1.28 {interpreted +} { $op 1 2 3000000000000000000000 } 3000000000000000000003
153     test mathop-1.29 {interpreted +: errors} -returnCodes error -body {
154         $op x 0
155     } -result {can't use non-numeric string as operand of "+"}
156     test mathop-1.30 {interpreted +: errors} -returnCodes error -body {
157         $op nan 0
158     } -result {can't use non-numeric floating-point value as operand of "+"}
159     test mathop-1.31 {interpreted +: errors} -returnCodes error -body {
160         $op 0 x
161     } -result {can't use non-numeric string as operand of "+"}
162     test mathop-1.32 {interpreted +: errors} -returnCodes error -body {
163         $op 0 nan
164     } -result {can't use non-numeric floating-point value as operand of "+"}
165     test mathop-1.33 {interpreted +: errors} -returnCodes error -body {
166         $op 0o8 0
167     } -result {can't use invalid octal number as operand of "+"}
168     test mathop-1.34 {interpreted +: errors} -returnCodes error -body {
169         $op 0 0o8
170     } -result {can't use invalid octal number as operand of "+"}
171     test mathop-1.35 {interpreted +: errors} -returnCodes error -body {
172         $op 0 [error expectedError]
173     } -result expectedError
174     test mathop-1.36 {interpreted +: argument processing order} -body {
175         list [catch {
176             $op [set x 0] [incr x] NaN [incr x] [error expected] [incr x]
177         } msg] $msg $x
178     } -result {1 expected 2}
179
180     test mathop-2.1 {compiled *} { * } 1
181     test mathop-2.2 {compiled *} { * 2 } 2
182     test mathop-2.3 {compiled *} { * 2 3 } 6
183     test mathop-2.4 {compiled *} { * 2 3 4 } 24
184     test mathop-2.5 {compiled *} { * 1.0 2 3 } 6.0
185     test mathop-2.6 {compiled *} { * 1 2 3.0 } 6.0
186     test mathop-2.7 {compiled *} { * 100000000000 2 3 } 600000000000
187     test mathop-2.8 {compiled *} { * 1 2 300000000000 } 600000000000
188     test mathop-2.9 {compiled *} { * 1000000000000000000000 2 3 } 6000000000000000000000
189     test mathop-2.10 {compiled *} { * 1 2 3000000000000000000000 } 6000000000000000000000
190     test mathop-2.11 {compiled *: errors} -returnCodes error -body {
191         * x 0
192     } -result {can't use non-numeric string as operand of "*"}
193     test mathop-2.12 {compiled *: errors} -returnCodes error -body {
194         * nan 0
195     } -result {can't use non-numeric floating-point value as operand of "*"}
196     test mathop-2.13 {compiled *: errors} -returnCodes error -body {
197         * 0 x
198     } -result {can't use non-numeric string as operand of "*"}
199     test mathop-2.14 {compiled *: errors} -returnCodes error -body {
200         * 0 nan
201     } -result {can't use non-numeric floating-point value as operand of "*"}
202     test mathop-2.15 {compiled *: errors} -returnCodes error -body {
203         * 0o8 0
204     } -result {can't use invalid octal number as operand of "*"}
205     test mathop-2.16 {compiled *: errors} -returnCodes error -body {
206         * 0 0o8
207     } -result {can't use invalid octal number as operand of "*"}
208     test mathop-2.17 {compiled *: errors} -returnCodes error -body {
209         * 0 [error expectedError]
210     } -result expectedError
211     test mathop-2.18 {compiled *: argument processing order} -body {
212         # Bytecode compilation known hard for 3+ arguments
213         list [catch {
214             * [set x 0] [incr x] NaN [incr x] [error expected] [incr x]
215         } msg] $msg $x
216     } -result {1 expected 2}
217     set op *
218     test mathop-2.19 {interpreted *} { $op } 1
219     test mathop-2.20 {interpreted *} { $op 2 } 2
220     test mathop-2.21 {interpreted *} { $op 2 3 } 6
221     test mathop-2.22 {interpreted *} { $op 2 3 4 } 24
222     test mathop-2.23 {interpreted *} { $op 1.0 2 3 } 6.0
223     test mathop-2.24 {interpreted *} { $op 1 2 3.0 } 6.0
224     test mathop-2.25 {interpreted *} { $op 100000000000 2 3 } 600000000000
225     test mathop-2.26 {interpreted *} { $op 1 2 300000000000 } 600000000000
226     test mathop-2.27 {interpreted *} { $op 1000000000000000000000 2 3 } 6000000000000000000000
227     test mathop-2.28 {interpreted *} { $op 1 2 3000000000000000000000 } 6000000000000000000000
228     test mathop-2.29 {interpreted *: errors} -returnCodes error -body {
229         $op x 0
230     } -result {can't use non-numeric string as operand of "*"}
231     test mathop-2.30 {interpreted *: errors} -returnCodes error -body {
232         $op nan 0
233     } -result {can't use non-numeric floating-point value as operand of "*"}
234     test mathop-2.31 {interpreted *: errors} -returnCodes error -body {
235         $op 0 x
236     } -result {can't use non-numeric string as operand of "*"}
237     test mathop-2.32 {interpreted *: errors} -returnCodes error -body {
238         $op 0 nan
239     } -result {can't use non-numeric floating-point value as operand of "*"}
240     test mathop-2.33 {interpreted *: errors} -returnCodes error -body {
241         $op 0o8 0
242     } -result {can't use invalid octal number as operand of "*"}
243     test mathop-2.34 {interpreted *: errors} -returnCodes error -body {
244         $op 0 0o8
245     } -result {can't use invalid octal number as operand of "*"}
246     test mathop-2.35 {interpreted *: errors} -returnCodes error -body {
247         $op 0 [error expectedError]
248     } -result expectedError
249     test mathop-2.36 {interpreted *: argument processing order} -body {
250         list [catch {
251             $op [set x 0] [incr x] NaN [incr x] [error expected] [incr x]
252         } msg] $msg $x
253     } -result {1 expected 2}
254
255     test mathop-3.1 {compiled !} {! 0} 1
256     test mathop-3.2 {compiled !} {! 1} 0
257     test mathop-3.3 {compiled !} {! false} 1
258     test mathop-3.4 {compiled !} {! true} 0
259     test mathop-3.5 {compiled !} {! 0.0} 1
260     test mathop-3.6 {compiled !} {! 10000000000} 0
261     test mathop-3.7 {compiled !} {! 10000000000000000000000000} 0
262     test mathop-3.8 {compiled !: errors} -body {
263         ! foobar
264     } -returnCodes error -result {can't use non-numeric string as operand of "!"}
265     test mathop-3.9 {compiled !: errors} -body {
266         ! 0 0
267     } -returnCodes error -result "wrong # args: should be \"! boolean\""
268     test mathop-3.10 {compiled !: errors} -body {
269         !
270     } -returnCodes error -result "wrong # args: should be \"! boolean\""
271     set op !
272     test mathop-3.11 {interpreted !} {$op 0} 1
273     test mathop-3.12 {interpreted !} {$op 1} 0
274     test mathop-3.13 {interpreted !} {$op false} 1
275     test mathop-3.14 {interpreted !} {$op true} 0
276     test mathop-3.15 {interpreted !} {$op 0.0} 1
277     test mathop-3.16 {interpreted !} {$op 10000000000} 0
278     test mathop-3.17 {interpreted !} {$op 10000000000000000000000000} 0
279     test mathop-3.18 {interpreted !: errors} -body {
280         $op foobar
281     } -returnCodes error -result {can't use non-numeric string as operand of "!"}
282     test mathop-3.19 {interpreted !: errors} -body {
283         $op 0 0
284     } -returnCodes error -result "wrong # args: should be \"! boolean\""
285     test mathop-3.20 {interpreted !: errors} -body {
286         $op
287     } -returnCodes error -result "wrong # args: should be \"! boolean\""
288     test mathop-3.21 {compiled !: error} -returnCodes error -body {
289         ! NaN
290     } -result {can't use non-numeric floating-point value as operand of "!"}
291     test mathop-3.22 {interpreted !: error} -returnCodes error -body {
292         $op NaN
293     } -result {can't use non-numeric floating-point value as operand of "!"}
294
295     test mathop-4.1 {compiled ~} {~ 0} -1
296     test mathop-4.2 {compiled ~} {~ 1} -2
297     test mathop-4.3 {compiled ~} {~ 31} -32
298     test mathop-4.4 {compiled ~} {~ -127} 126
299     test mathop-4.5 {compiled ~} {~ -0} -1
300     test mathop-4.6 {compiled ~} {~ 10000000000} -10000000001
301     test mathop-4.7 {compiled ~} {~ 10000000000000000000000000} -10000000000000000000000001
302     test mathop-4.8 {compiled ~: errors} -body {
303         ~ foobar
304     } -returnCodes error -result {can't use non-numeric string as operand of "~"}
305     test mathop-4.9 {compiled ~: errors} -body {
306         ~ 0 0
307     } -returnCodes error -result "wrong # args: should be \"~ integer\""
308     test mathop-4.10 {compiled ~: errors} -body {
309         ~
310     } -returnCodes error -result "wrong # args: should be \"~ integer\""
311     test mathop-4.11 {compiled ~: errors} -returnCodes error -body {
312         ~ 0.0
313     } -result {can't use floating-point value as operand of "~"}
314     test mathop-4.12 {compiled ~: errors} -returnCodes error -body {
315         ~ NaN
316     } -result {can't use non-numeric floating-point value as operand of "~"}
317     set op ~
318     test mathop-4.13 {interpreted ~} {$op 0} -1
319     test mathop-4.14 {interpreted ~} {$op 1} -2
320     test mathop-4.15 {interpreted ~} {$op 31} -32
321     test mathop-4.16 {interpreted ~} {$op -127} 126
322     test mathop-4.17 {interpreted ~} {$op -0} -1
323     test mathop-4.18 {interpreted ~} {$op 10000000000} -10000000001
324     test mathop-4.19 {interpreted ~} {$op 10000000000000000000000000} -10000000000000000000000001
325     test mathop-4.20 {interpreted ~: errors} -body {
326         $op foobar
327     } -returnCodes error -result {can't use non-numeric string as operand of "~"}
328     test mathop-4.21 {interpreted ~: errors} -body {
329         $op 0 0
330     } -returnCodes error -result "wrong # args: should be \"~ integer\""
331     test mathop-4.22 {interpreted ~: errors} -body {
332         $op
333     } -returnCodes error -result "wrong # args: should be \"~ integer\""
334     test mathop-4.23 {interpreted ~: errors} -returnCodes error -body {
335         $op 0.0
336     } -result {can't use floating-point value as operand of "~"}
337     test mathop-4.24 {interpreted ~: errors} -returnCodes error -body {
338         $op NaN
339     } -result {can't use non-numeric floating-point value as operand of "~"}
340
341     test mathop-5.1 {compiled eq} {eq {} a} 0
342     test mathop-5.2 {compiled eq} {eq a a} 1
343     test mathop-5.3 {compiled eq} {eq a {}} 0
344     test mathop-5.4 {compiled eq} {eq a b} 0
345     test mathop-5.5 {compiled eq} { eq } 1
346     test mathop-5.6 {compiled eq} {eq a} 1
347     test mathop-5.7 {compiled eq} {eq a a a} 1
348     test mathop-5.8 {compiled eq} {eq a a b} 0
349     test mathop-5.9 {compiled eq} -body {
350         eq a b [error foobar]
351     } -returnCodes error -result foobar
352     test mathop-5.10 {compiled eq} {eq NaN Na NaN} 0
353     set op eq
354     test mathop-5.11 {interpreted eq} {$op {} a} 0
355     test mathop-5.12 {interpreted eq} {$op a a} 1
356     test mathop-5.13 {interpreted eq} {$op a {}} 0
357     test mathop-5.14 {interpreted eq} {$op a b} 0
358     test mathop-5.15 {interpreted eq} { $op } 1
359     test mathop-5.16 {interpreted eq} {$op a} 1
360     test mathop-5.17 {interpreted eq} {$op a a a} 1
361     test mathop-5.18 {interpreted eq} {$op a a b} 0
362     test mathop-5.19 {interpreted eq} -body {
363         $op a b [error foobar]
364     } -returnCodes error -result foobar
365     test mathop-5.20 {interpreted eq} {$op NaN Na NaN} 0
366
367     variable big1      12135435435354435435342423948763867876
368     variable big2       2746237174783836746262564892918327847
369     variable wide1                             12345678912345
370     variable wide2                             87321847232215
371     variable small1                                     87345
372     variable small2                                     16753
373
374     test mathop-6.1 {compiled &} { & } -1
375     test mathop-6.2 {compiled &} { & 1 } 1
376     test mathop-6.3 {compiled &} { & 1 2 } 0
377     test mathop-6.4 {compiled &} { & 3 7 6 } 2
378     test mathop-6.5 {compiled &} -returnCodes error -body {
379         & 1.0 2 3
380     } -result {can't use floating-point value as operand of "&"}
381     test mathop-6.6 {compiled &} -returnCodes error -body {
382         & 1 2 3.0
383     } -result {can't use floating-point value as operand of "&"}
384     test mathop-6.7 {compiled &} { & 100000000002 18 -126 } 2
385     test mathop-6.8 {compiled &} { & 0xff 0o377 333333333333 } 85
386     test mathop-6.9 {compiled &} { & 1000000000000000000002 18 -126 } 2
387     test mathop-6.10 {compiled &} { & 0xff 0o377 3333333333333333333333 } 85
388     test mathop-6.11 {compiled &: errors} -returnCodes error -body {
389         & x 0
390     } -result {can't use non-numeric string as operand of "&"}
391     test mathop-6.12 {compiled &: errors} -returnCodes error -body {
392         & nan 0
393     } -result {can't use non-numeric floating-point value as operand of "&"}
394     test mathop-6.13 {compiled &: errors} -returnCodes error -body {
395         & 0 x
396     } -result {can't use non-numeric string as operand of "&"}
397     test mathop-6.14 {compiled &: errors} -returnCodes error -body {
398         & 0 nan
399     } -result {can't use non-numeric floating-point value as operand of "&"}
400     test mathop-6.15 {compiled &: errors} -returnCodes error -body {
401         & 0o8 0
402     } -result {can't use invalid octal number as operand of "&"}
403     test mathop-6.16 {compiled &: errors} -returnCodes error -body {
404         & 0 0o8
405     } -result {can't use invalid octal number as operand of "&"}
406     test mathop-6.17 {compiled &: errors} -returnCodes error -body {
407         & 0 [error expectedError]
408     } -result expectedError
409     test mathop-6.18 {compiled &: argument processing order} -body {
410         # Bytecode compilation known hard for 3+ arguments
411         list [catch {
412             & [set x 0] [incr x] NaN [incr x] [error expected] [incr x]
413         } msg] $msg $x
414     } -result {1 expected 2}
415     set op &
416     test mathop-6.19 {interpreted &} { $op } -1
417     test mathop-6.20 {interpreted &} { $op 1 } 1
418     test mathop-6.21 {interpreted &} { $op 1 2 } 0
419     test mathop-6.22 {interpreted &} { $op 3 7 6 } 2
420     test mathop-6.23 {interpreted &} -returnCodes error -body {
421         $op 1.0 2 3
422     } -result {can't use floating-point value as operand of "&"}
423     test mathop-6.24 {interpreted &} -returnCodes error -body {
424         $op 1 2 3.0
425     } -result {can't use floating-point value as operand of "&"}
426     test mathop-6.25 {interpreted &} { $op 100000000002 18 -126 } 2
427     test mathop-6.26 {interpreted &} { $op 0xff 0o377 333333333333 } 85
428     test mathop-6.27 {interpreted &} { $op 1000000000000000000002 18 -126 } 2
429     test mathop-6.28 {interpreted &} { $op 0xff 0o377 3333333333333333333333 } 85
430     test mathop-6.29 {interpreted &: errors} -returnCodes error -body {
431         $op x 0
432     } -result {can't use non-numeric string as operand of "&"}
433     test mathop-6.30 {interpreted &: errors} -returnCodes error -body {
434         $op nan 0
435     } -result {can't use non-numeric floating-point value as operand of "&"}
436     test mathop-6.31 {interpreted &: errors} -returnCodes error -body {
437         $op 0 x
438     } -result {can't use non-numeric string as operand of "&"}
439     test mathop-6.32 {interpreted &: errors} -returnCodes error -body {
440         $op 0 nan
441     } -result {can't use non-numeric floating-point value as operand of "&"}
442     test mathop-6.33 {interpreted &: errors} -returnCodes error -body {
443         $op 0o8 0
444     } -result {can't use invalid octal number as operand of "&"}
445     test mathop-6.34 {interpreted &: errors} -returnCodes error -body {
446         $op 0 0o8
447     } -result {can't use invalid octal number as operand of "&"}
448     test mathop-6.35 {interpreted &: errors} -returnCodes error -body {
449         $op 0 [error expectedError]
450     } -result expectedError
451     test mathop-6.36 {interpreted &: argument processing order} -body {
452         list [catch {
453             $op [set x 0] [incr x] NaN [incr x] [error expected] [incr x]
454         } msg] $msg $x
455     } -result {1 expected 2}
456     test mathop-6.37 {& and bignums} {
457         list [& $big1 $big2] [$op $big1 $big2]
458     } {712439449294653815890598856501796 712439449294653815890598856501796}
459     test mathop-6.38 {& and bignums} {
460         list [& $big1 $wide2] [$op $big1 $wide2]
461     } {78521450111684 78521450111684}
462     test mathop-6.39 {& and bignums} {
463         list [& $big1 $small2] [$op $big1 $small2]
464     } {96 96}
465     test mathop-6.40 {& and bignums} {
466         list [& $wide1 $big2] [$op $wide1 $big2]
467     } {2371422390785 2371422390785}
468     test mathop-6.41 {& and bignums} {
469         list [& $wide1 $wide2] [$op $wide1 $wide2]
470     } {12275881497169 12275881497169}
471     test mathop-6.42 {& and bignums} {
472         list [& $wide1 $small2] [$op $wide1 $small2]
473     } {16721 16721}
474     test mathop-6.43 {& and bignums} {
475         list [& $small1 $big2] [$op $small1 $big2]
476     } {33 33}
477     test mathop-6.44 {& and bignums} {
478         list [& $small1 $wide2] [$op $small1 $wide2]
479     } {87057 87057}
480     test mathop-6.45 {& and bignums} {
481         list [& $small1 $small2] [$op $small1 $small2]
482     } {16689 16689}
483
484     test mathop-7.1 {compiled |} { | } 0
485     test mathop-7.2 {compiled |} { | 1 } 1
486     test mathop-7.3 {compiled |} { | 1 2 } 3
487     test mathop-7.4 {compiled |} { | 3 7 6 } 7
488     test mathop-7.5 {compiled |} -returnCodes error -body {
489         | 1.0 2 3
490     } -result {can't use floating-point value as operand of "|"}
491     test mathop-7.6 {compiled |} -returnCodes error -body {
492         | 1 2 3.0
493     } -result {can't use floating-point value as operand of "|"}
494     test mathop-7.7 {compiled |} { | 100000000002 18 -126 } -110
495     test mathop-7.8 {compiled |} { | 0xff 0o377 333333333333 } 333333333503
496     test mathop-7.9 {compiled |} { | 1000000000000000000002 18 -126 } -110
497     test mathop-7.10 {compiled |} { | 0xff 0o377 3333333333333333333333 } 3333333333333333333503
498     test mathop-7.11 {compiled |: errors} -returnCodes error -body {
499         | x 0
500     } -result {can't use non-numeric string as operand of "|"}
501     test mathop-7.12 {compiled |: errors} -returnCodes error -body {
502         | nan 0
503     } -result {can't use non-numeric floating-point value as operand of "|"}
504     test mathop-7.13 {compiled |: errors} -returnCodes error -body {
505         | 0 x
506     } -result {can't use non-numeric string as operand of "|"}
507     test mathop-7.14 {compiled |: errors} -returnCodes error -body {
508         | 0 nan
509     } -result {can't use non-numeric floating-point value as operand of "|"}
510     test mathop-7.15 {compiled |: errors} -returnCodes error -body {
511         | 0o8 0
512     } -result {can't use invalid octal number as operand of "|"}
513     test mathop-7.16 {compiled |: errors} -returnCodes error -body {
514         | 0 0o8
515     } -result {can't use invalid octal number as operand of "|"}
516     test mathop-7.17 {compiled |: errors} -returnCodes error -body {
517         | 0 [error expectedError]
518     } -result expectedError
519     test mathop-7.18 {compiled |: argument processing order} -body {
520         # Bytecode compilation known hard for 3+ arguments
521         list [catch {
522             | [set x 0] [incr x] NaN [incr x] [error expected] [incr x]
523         } msg] $msg $x
524     } -result {1 expected 2}
525     set op |
526     test mathop-7.19 {interpreted |} { $op } 0
527     test mathop-7.20 {interpreted |} { $op 1 } 1
528     test mathop-7.21 {interpreted |} { $op 1 2 } 3
529     test mathop-7.22 {interpreted |} { $op 3 7 6 } 7
530     test mathop-7.23 {interpreted |} -returnCodes error -body {
531         $op 1.0 2 3
532     } -result {can't use floating-point value as operand of "|"}
533     test mathop-7.24 {interpreted |} -returnCodes error -body {
534         $op 1 2 3.0
535     } -result {can't use floating-point value as operand of "|"}
536     test mathop-7.25 {interpreted |} { $op 100000000002 18 -126 } -110
537     test mathop-7.26 {interpreted |} { $op 0xff 0o377 333333333333 } 333333333503
538     test mathop-7.27 {interpreted |} { $op 1000000000000000000002 18 -126 } -110
539     test mathop-7.28 {interpreted |} { $op 0xff 0o377 3333333333333333333333 } 3333333333333333333503
540     test mathop-7.29 {interpreted |: errors} -returnCodes error -body {
541         $op x 0
542     } -result {can't use non-numeric string as operand of "|"}
543     test mathop-7.30 {interpreted |: errors} -returnCodes error -body {
544         $op nan 0
545     } -result {can't use non-numeric floating-point value as operand of "|"}
546     test mathop-7.31 {interpreted |: errors} -returnCodes error -body {
547         $op 0 x
548     } -result {can't use non-numeric string as operand of "|"}
549     test mathop-7.32 {interpreted |: errors} -returnCodes error -body {
550         $op 0 nan
551     } -result {can't use non-numeric floating-point value as operand of "|"}
552     test mathop-7.33 {interpreted |: errors} -returnCodes error -body {
553         $op 0o8 0
554     } -result {can't use invalid octal number as operand of "|"}
555     test mathop-7.34 {interpreted |: errors} -returnCodes error -body {
556         $op 0 0o8
557     } -result {can't use invalid octal number as operand of "|"}
558     test mathop-7.35 {interpreted |: errors} -returnCodes error -body {
559         $op 0 [error expectedError]
560     } -result expectedError
561     test mathop-7.36 {interpreted |: argument processing order} -body {
562         list [catch {
563             $op [set x 0] [incr x] NaN [incr x] [error expected] [incr x]
564         } msg] $msg $x
565     } -result {1 expected 2}
566     test mathop-7.37 {| and bignums} {
567         list [| $big1 $big2] [$op $big1 $big2]
568     } {14880960170688977527789098242825693927 14880960170688977527789098242825693927}
569     test mathop-7.38 {| and bignums} {
570         list [| $big1 $wide2] [$op $big1 $wide2]
571     } {12135435435354435435342432749160988407 12135435435354435435342432749160988407}
572     test mathop-7.39 {| and bignums} {
573         list [| $big1 $small2] [$op $big1 $small2]
574     } {12135435435354435435342423948763884533 12135435435354435435342423948763884533}
575     test mathop-7.40 {| and bignums} {
576         list [| $wide1 $big2] [$op $wide1 $big2]
577     } {2746237174783836746262574867174849407 2746237174783836746262574867174849407}
578     test mathop-7.41 {| and bignums} {
579         list [| $wide1 $wide2] [$op $wide1 $wide2]
580     } {87391644647391 87391644647391}
581     test mathop-7.42 {| and bignums} {
582         list [| $wide1 $small2] [$op $wide1 $small2]
583     } {12345678912377 12345678912377}
584     test mathop-7.43 {| and bignums} {
585         list [| $small1 $big2] [$op $small1 $big2]
586     } {2746237174783836746262564892918415159 2746237174783836746262564892918415159}
587     test mathop-7.44 {| and bignums} {
588         list [| $small1 $wide2] [$op $small1 $wide2]
589     } {87321847232503 87321847232503}
590     test mathop-7.45 {| and bignums} {
591         list [| $small1 $small2] [$op $small1 $small2]
592     } {87409 87409}
593
594     test mathop-8.1 {compiled ^} { ^ } 0
595     test mathop-8.2 {compiled ^} { ^ 1 } 1
596     test mathop-8.3 {compiled ^} { ^ 1 2 } 3
597     test mathop-8.4 {compiled ^} { ^ 3 7 6 } 2
598     test mathop-8.5 {compiled ^} -returnCodes error -body {
599         ^ 1.0 2 3
600     } -result {can't use floating-point value as operand of "^"}
601     test mathop-8.6 {compiled ^} -returnCodes error -body {
602         ^ 1 2 3.0
603     } -result {can't use floating-point value as operand of "^"}
604     test mathop-8.7 {compiled ^} { ^ 100000000002 18 -126 } -100000000110
605     test mathop-8.8 {compiled ^} { ^ 0xff 0o377 333333333333 } 333333333333
606     test mathop-8.9 {compiled ^} { ^ 1000000000000000000002 18 -126 } -1000000000000000000110
607     test mathop-8.10 {compiled ^} { ^ 0xff 0o377 3333333333333333333333 } 3333333333333333333333
608     test mathop-8.11 {compiled ^: errors} -returnCodes error -body {
609         ^ x 0
610     } -result {can't use non-numeric string as operand of "^"}
611     test mathop-8.12 {compiled ^: errors} -returnCodes error -body {
612         ^ nan 0
613     } -result {can't use non-numeric floating-point value as operand of "^"}
614     test mathop-8.13 {compiled ^: errors} -returnCodes error -body {
615         ^ 0 x
616     } -result {can't use non-numeric string as operand of "^"}
617     test mathop-8.14 {compiled ^: errors} -returnCodes error -body {
618         ^ 0 nan
619     } -result {can't use non-numeric floating-point value as operand of "^"}
620     test mathop-8.15 {compiled ^: errors} -returnCodes error -body {
621         ^ 0o8 0
622     } -result {can't use invalid octal number as operand of "^"}
623     test mathop-8.16 {compiled ^: errors} -returnCodes error -body {
624         ^ 0 0o8
625     } -result {can't use invalid octal number as operand of "^"}
626     test mathop-8.17 {compiled ^: errors} -returnCodes error -body {
627         ^ 0 [error expectedError]
628     } -result expectedError
629     test mathop-8.18 {compiled ^: argument processing order} -body {
630         # Bytecode compilation known hard for 3+ arguments
631         list [catch {
632             ^ [set x 0] [incr x] NaN [incr x] [error expected] [incr x]
633         } msg] $msg $x
634     } -result {1 expected 2}
635     set op ^
636     test mathop-8.19 {interpreted ^} { $op } 0
637     test mathop-8.20 {interpreted ^} { $op 1 } 1
638     test mathop-8.21 {interpreted ^} { $op 1 2 } 3
639     test mathop-8.22 {interpreted ^} { $op 3 7 6 } 2
640     test mathop-8.23 {interpreted ^} -returnCodes error -body {
641         $op 1.0 2 3
642     } -result {can't use floating-point value as operand of "^"}
643     test mathop-8.24 {interpreted ^} -returnCodes error -body {
644         $op 1 2 3.0
645     } -result {can't use floating-point value as operand of "^"}
646     test mathop-8.25 {interpreted ^} { $op 100000000002 18 -126 } -100000000110
647     test mathop-8.26 {interpreted ^} { $op 0xff 0o377 333333333333 } 333333333333
648     test mathop-8.27 {interpreted ^} { $op 1000000000000000000002 18 -126 } -1000000000000000000110
649     test mathop-8.28 {interpreted ^} { $op 0xff 0o377 3333333333333333333333 } 3333333333333333333333
650     test mathop-8.29 {interpreted ^: errors} -returnCodes error -body {
651         $op x 0
652     } -result {can't use non-numeric string as operand of "^"}
653     test mathop-8.30 {interpreted ^: errors} -returnCodes error -body {
654         $op nan 0
655     } -result {can't use non-numeric floating-point value as operand of "^"}
656     test mathop-8.31 {interpreted ^: errors} -returnCodes error -body {
657         $op 0 x
658     } -result {can't use non-numeric string as operand of "^"}
659     test mathop-8.32 {interpreted ^: errors} -returnCodes error -body {
660         $op 0 nan
661     } -result {can't use non-numeric floating-point value as operand of "^"}
662     test mathop-8.33 {interpreted ^: errors} -returnCodes error -body {
663         $op 0o8 0
664     } -result {can't use invalid octal number as operand of "^"}
665     test mathop-8.34 {interpreted ^: errors} -returnCodes error -body {
666         $op 0 0o8
667     } -result {can't use invalid octal number as operand of "^"}
668     test mathop-8.35 {interpreted ^: errors} -returnCodes error -body {
669         $op 0 [error expectedError]
670     } -result expectedError
671     test mathop-8.36 {interpreted ^: argument processing order} -body {
672         list [catch {
673             $op [set x 0] [incr x] NaN [incr x] [error expected] [incr x]
674         } msg] $msg $x
675     } -result {1 expected 2}
676     test mathop-8.37 {^ and bignums} {
677         list [^ $big1 $big2] [$op $big1 $big2]
678     } {14880247731239682873973207643969192131 14880247731239682873973207643969192131}
679     test mathop-8.38 {^ and bignums} {
680         list [^ $big1 $wide2] [$op $big1 $wide2]
681     } {12135435435354435435342354227710876723 12135435435354435435342354227710876723}
682     test mathop-8.39 {^ and bignums} {
683         list [^ $big1 $small2] [$op $big1 $small2]
684     } {12135435435354435435342423948763884437 12135435435354435435342423948763884437}
685     test mathop-8.40 {^ and bignums} {
686         list [^ $wide1 $big2] [$op $wide1 $big2]
687     } {2746237174783836746262572495752458622 2746237174783836746262572495752458622}
688     test mathop-8.41 {^ and bignums} {
689         list [^ $wide1 $wide2] [$op $wide1 $wide2]
690     } {75115763150222 75115763150222}
691     test mathop-8.42 {^ and bignums} {
692         list [^ $wide1 $small2] [$op $wide1 $small2]
693     } {12345678895656 12345678895656}
694     test mathop-8.43 {^ and bignums} {
695         list [^ $small1 $big2] [$op $small1 $big2]
696     } {2746237174783836746262564892918415126 2746237174783836746262564892918415126}
697     test mathop-8.44 {^ and bignums} {
698         list [^ $small1 $wide2] [$op $small1 $wide2]
699     } {87321847145446 87321847145446}
700     test mathop-8.45 {^ and bignums} {
701         list [^ $small1 $small2] [$op $small1 $small2]
702     } {70720 70720}
703
704     # TODO: % ** << >>  - /  == != < <= > >=  ne  in ni
705
706     test mathop-13.100 {compiled -: argument processing order} -body {
707       # Bytecode compilation known hard for 3+ arguments
708       list [catch {
709           - [set x 0] [incr x] NaN [incr x] [error expected] [incr x]
710       } msg] $msg $x
711     } -result {1 expected 2}
712
713     test mathop-14.100 {compiled /: argument processing order} -body {
714       # Bytecode compilation known hard for 3+ arguments
715       list [catch {
716           / [set x 0] [incr x] NaN [incr x] [error expected] [incr x]
717       } msg] $msg $x
718     } -result {1 expected 2}
719 }
720
721 test mathop-20.1 { zero args, return unit } {
722     set res {}
723     foreach op {+ * & ^ | ** < <= > >= == eq} {
724         lappend res [TestOp $op]
725     }
726     set res
727 } {0 1 -1 0 0 1 1 1 1 1 1 1}
728 test mathop-20.2 { zero args, not allowed } {
729     set exp {}
730     foreach op {~ ! << >> % != ne in ni - /} {
731         set res [TestOp $op]
732         if {[string match "wrong # args: should be * TCL WRONGARGS" $res]} {
733             lappend exp 0
734         } else {
735             lappend exp $res
736         }
737     }
738     set exp
739 } {0 0 0 0 0 0 0 0 0 0 0}
740 test mathop-20.3 { one arg } {
741     set res {}
742     foreach val {7 8.3} {
743         foreach op {+ ** - * / < <= > >= == eq !} {
744             lappend res [TestOp $op $val]
745         }
746     }
747     set res
748 } [list 7   7   -7   7   [expr {1.0/7.0}] 1 1 1 1 1 1 0 \
749         8.3 8.3 -8.3 8.3 [expr {1.0/8.3}] 1 1 1 1 1 1 0]
750 test mathop-20.4 { one arg, integer only ops } {
751     set res {}
752     foreach val {23} {
753         foreach op {& | ^ ~} {
754             lappend res [TestOp $op $val]
755         }
756     }
757     set res
758 } [list 23 23 23 -24]
759 test mathop-20.5 { one arg, not allowed } {
760     set exp {}
761     foreach op {% != ne in ni << >>} {
762         set res [TestOp $op 1]
763         if {[string match "wrong # args: should be * TCL WRONGARGS" $res]} {
764             lappend exp 0
765         } else {
766             lappend exp $res
767         }
768     }
769     set exp
770 } {0 0 0 0 0 0 0}
771 test mathop-20.6 { one arg, error } {
772     set res {}
773     set exp {}
774     foreach vals {x {1 x} {1 1 x} {1 x 1}} {
775         # skipping - for now, knownbug...
776         foreach op {+ * / & | ^ **} {
777             lappend res [TestOp $op {*}$vals]
778             lappend exp "can't use non-numeric string as operand of \"$op\"\
779                 ARITH DOMAIN {non-numeric string}"
780         }
781     }
782     foreach op {+ * / & | ^ **} {
783         lappend res [TestOp $op NaN 1]
784         lappend exp "can't use non-numeric floating-point value as operand of \"$op\"\
785             ARITH DOMAIN {non-numeric floating-point value}"
786     }
787     expr {$res eq $exp ? 0 : $res}
788 } 0
789 test mathop-20.7 { multi arg } {
790     set res {}
791     foreach vals {{1 2} {3 4 5} {4 3 2 1}} {
792         foreach op {+ - * /} {
793             lappend res [TestOp $op {*}$vals]
794         }
795     }
796     set res
797 } [list 3 -1 2 0  12 -6 60 0  10 -2 24 0]
798 test mathop-20.8 { multi arg, double } {
799     set res {}
800     foreach vals {{1.0 2} {3.0 4 5} {4 3.0 2 1}
801             {1.0 -1.0 1e-18} {1.0 1.0 1e-18}} {
802         foreach op {+ - * /} {
803             lappend res [TestOp $op {*}$vals]
804         }
805     }
806     set res
807 } [list 3.0 -1.0 2.0 0.5  12.0 -6.0 60.0 0.15  10.0 -2.0 24.0 [expr {2.0/3}] 1e-18 2.0 -1e-18 [expr {-1.0/1e-18}] 2.0 -1e-18 1e-18 [expr {1.0/1e-18}]]
808
809 test mathop-21.1 { unary ops, bitnot } {
810     set res {}
811     lappend res [TestOp ~ 7]
812     lappend res [TestOp ~ -5]
813     lappend res [TestOp ~ 354657483923456]
814     lappend res [TestOp ~ 123456789123456789123456789]
815     set res
816 } [list -8 4 -354657483923457 -123456789123456789123456790]
817 test mathop-21.2 { unary ops, logical not } {
818     set res {}
819     lappend res [TestOp ! 0]
820     lappend res [TestOp ! 1]
821     lappend res [TestOp ! true]
822     lappend res [TestOp ! false]
823     lappend res [TestOp ! 37]
824     lappend res [TestOp ! 8.5]
825     set res
826 } [list 1 0 0 1 0 0]
827 test mathop-21.3 { unary ops, negation } {
828     set res {}
829     lappend res [TestOp -  7.2]
830     lappend res [TestOp - -5]
831     lappend res [TestOp - -2147483648]                  ;# -2**31
832     lappend res [TestOp - -9223372036854775808]         ;# -2**63
833     lappend res [TestOp -  354657483923456]             ;# wide
834     lappend res [TestOp -  123456789123456789123456789] ;# big
835     set res
836 } [list -7.2 5 2147483648 9223372036854775808 -354657483923456 \
837            -123456789123456789123456789]
838 test mathop-21.4 { unary ops, inversion } {
839     set res {}
840     lappend res [TestOp / 1]
841     lappend res [TestOp / 5]
842     lappend res [TestOp / 5.6]
843     lappend res [TestOp / -8]
844     lappend res [TestOp /  354657483923456]             ;# wide
845     lappend res [TestOp /  123456789123456789123456789] ;# big
846     set res
847 } [list 1.0 0.2 0.17857142857142858 -0.125 \
848            2.8196218755553604e-15 8.10000006561e-27]
849 test mathop-21.5 { unary ops, bad values } {
850     set res {}
851     set exp {}
852     lappend res [TestOp / x]
853     lappend exp "can't use non-numeric string as operand of \"/\" ARITH DOMAIN {non-numeric string}"
854     lappend res [TestOp - x]
855     lappend exp "can't use non-numeric string as operand of \"-\" ARITH DOMAIN {non-numeric string}"
856     lappend res [TestOp ~ x]
857     lappend exp "can't use non-numeric string as operand of \"~\" ARITH DOMAIN {non-numeric string}"
858     lappend res [TestOp ! x]
859     lappend exp "can't use non-numeric string as operand of \"!\" ARITH DOMAIN {non-numeric string}"
860     lappend res [TestOp ~ 5.0]
861     lappend exp "can't use floating-point value as operand of \"~\" ARITH DOMAIN {floating-point value}"
862     expr {$res eq $exp ? 0 : $res}
863 } 0
864 test mathop-21.6 { unary ops, too many } {
865     set exp {}
866     foreach op {~ !} {
867         set res [TestOp $op 7 8]
868         if {[string match "wrong # args: should be * TCL WRONGARGS" $res]} {
869             lappend exp 0
870         } else {
871             lappend exp $res
872         }
873     }
874     set exp
875 } {0 0}
876
877 test mathop-22.1 { bitwise ops } {
878     set res {}
879     foreach vals {5 {1 6} {1 2 3} {1 2 3 4}} {
880         foreach op {& | ^} {
881             lappend res [TestOp $op {*}$vals]
882         }
883     }
884     set res
885 } [list 5 5 5  0 7 7  0 3 0  0 7 4]
886 test mathop-22.2 { bitwise ops on bignums } {
887     set dig 50
888     set a 0x[string repeat 5 $dig]
889     set b 0x[string repeat 7 $dig]
890     set c 0x[string repeat 9 $dig]
891     set bn [expr {~$b}]
892     set cn [expr {~$c}]
893
894     set res {}
895     foreach vals [list [list $a $b] [list $a $c] [list $b $c] \
896                           [list $a $bn] [list $bn $c] [list $bn $cn]] {
897         foreach op {& | ^} {
898             lappend res [TestOp $op {*}$vals]
899         }
900     }
901     set exp {}
902     foreach d {5 7 2  1 D C  1 F E  0 -D -D  8 -9 -1  -0 -E E} {
903         if {[string match "-*" $d]} {
904             set d [format %X [expr {15-"0x[string range $d 1 end]"}]]
905             set val [expr {-"0x[string repeat $d $dig]"-1}]
906         } else {
907             set val [expr {"0x[string repeat $d $dig]"}]
908         }
909         lappend exp $val
910     }
911     expr {$exp eq $res ? 1 : "($res != $exp"}
912 } 1
913 test mathop-22.3 { bitwise ops } {
914     set big1      12135435435354435435342423948763867876
915     set big2       2746237174783836746262564892918327847
916     set wide1                             12345678912345
917     set wide2                             87321847232215
918     set small1                                     87345
919     set small2                                     16753
920
921     set res {}
922     foreach op {& | ^} {
923         lappend res [TestOp $op $big1   $big2]
924         lappend res [TestOp $op $big1   $wide2]
925         lappend res [TestOp $op $big1   $small2]
926         lappend res [TestOp $op $wide1  $big2]
927         lappend res [TestOp $op $wide1  $wide2]
928         lappend res [TestOp $op $wide1  $small2]
929         lappend res [TestOp $op $small1 $big2]
930         lappend res [TestOp $op $small1 $wide2]
931         lappend res [TestOp $op $small1 $small2]
932     }
933     set res
934 } [list \
935            712439449294653815890598856501796 \
936            78521450111684 \
937            96 \
938            2371422390785 \
939            12275881497169 \
940            16721 \
941            33 \
942            87057 \
943            16689 \
944            14880960170688977527789098242825693927 \
945            12135435435354435435342432749160988407 \
946            12135435435354435435342423948763884533 \
947            2746237174783836746262574867174849407 \
948            87391644647391 \
949            12345678912377 \
950            2746237174783836746262564892918415159 \
951            87321847232503 \
952            87409 \
953            14880247731239682873973207643969192131 \
954            12135435435354435435342354227710876723 \
955            12135435435354435435342423948763884437 \
956            2746237174783836746262572495752458622 \
957            75115763150222 \
958            12345678895656 \
959            2746237174783836746262564892918415126 \
960            87321847145446 \
961            70720 \
962           ]
963 test mathop-22.4 { unary ops, bad values } {
964     set res {}
965     set exp {}
966     foreach op {& | ^} {
967         lappend res [TestOp $op x 5]
968         lappend exp "can't use non-numeric string as operand of \"$op\" ARITH DOMAIN {non-numeric string}"
969         lappend res [TestOp $op 5 x]
970         lappend exp "can't use non-numeric string as operand of \"$op\" ARITH DOMAIN {non-numeric string}"
971     }
972     expr {$res eq $exp ? 0 : $res}
973 } 0
974
975 test mathop-23.1 { comparison ops, numerical } {
976     set res {}
977     set todo {5 {1 6} {1 2 2 3} {4 3 2 1} {5.0 5.0} {6 3 3 1} {5.0 5}}
978     lappend todo [list 2342476234762482734623842342 234827463876473 3434]
979     lappend todo [list 2653 453735910264536 453735910264537 2384762472634982746239847637]
980     lappend todo [list 2653 2384762472634982746239847637]
981     lappend todo [list 2653 -2384762472634982746239847637]
982     lappend todo [list 3789253678212653 -2384762472634982746239847637]
983     lappend todo [list 5.0 6 7.0 8 1e13 1945628567352654 1.1e20 \
984                           6734253647589123456784564378 2.3e50]
985     set a 7
986     lappend todo [list $a $a] ;# Same object
987     foreach vals $todo {
988         foreach op {< <= > >= == eq} {
989             lappend res [TestOp $op {*}$vals]
990         }
991     }
992     set res
993 } [list 1 1 1 1 1 1 \
994         1 1 0 0 0 0 \
995         0 1 0 0 0 0 \
996         0 0 1 1 0 0 \
997         0 1 0 1 1 1 \
998         0 0 0 1 0 0 \
999         0 1 0 1 1 0 \
1000         0 0 1 1 0 0 \
1001         1 1 0 0 0 0 \
1002         1 1 0 0 0 0 \
1003         0 0 1 1 0 0 \
1004         0 0 1 1 0 0 \
1005         1 1 0 0 0 0 \
1006         0 1 0 1 1 1 \
1007        ]
1008 test mathop-23.2 { comparison ops, string } {
1009     set res {}
1010     set todo {a {a b} {5 b b c} {d c b a} {xy xy} {gy ef ef ab}}
1011     set a x
1012     lappend todo [list $a $a]
1013     foreach vals $todo {
1014         foreach op {< <= > >= == eq} {
1015             lappend res [TestOp $op {*}$vals]
1016         }
1017     }
1018     set res
1019 } [list 1 1 1 1 1 1 \
1020         1 1 0 0 0 0 \
1021         0 1 0 0 0 0 \
1022         0 0 1 1 0 0 \
1023         0 1 0 1 1 1 \
1024         0 0 0 1 0 0 \
1025         0 1 0 1 1 1 \
1026        ]
1027 test mathop-23.3 { comparison ops, nonequal} {
1028     set res {}
1029     foreach vals {{a b} {17.0 0x11} {foo foo} {10 10}} {
1030         foreach op {!= ne} {
1031             lappend res [TestOp $op {*}$vals]
1032         }
1033     }
1034     set res
1035 } [list 1 1  0 1  0 0  0 0 ]
1036
1037 test mathop-24.1 { binary ops } {
1038     set res {}
1039     foreach vals {{3 5} {17 7} {199 5} {293234675763434238476239486 17} \
1040                   {5 1} {0 7}} {
1041         foreach op {% << >> in ni} {
1042             lappend res [TestOp $op {*}$vals]
1043         }
1044     }
1045     set res
1046 } [list 3 96 0 0 1  3 2176 0 0 1  4 6368 6 0 1 \
1047         14 38434855421664852505557661908992 2237203031642412097749 0 1 \
1048         0 10 2 0 1  0 0 0 0 1]
1049 test mathop-24.2 { binary ops, modulo } {
1050     # Test different combinations to get all code paths
1051     set res {}
1052
1053     set bigbig 14372423674564535234543545248972634923869
1054     set big       12135435435354435435342423948763867876
1055     set wide                              12345678912345
1056     set negwide                          -12345678912345
1057     set small                                          5
1058     set neg                                           -5
1059
1060     lappend res [TestOp % $bigbig  $big]
1061     lappend res [TestOp % $wide    $big]
1062     lappend res [TestOp % $negwide $big]
1063     lappend res [TestOp % $small   $big]
1064     lappend res [TestOp % $neg     $big]
1065     lappend res [TestOp % $small  $wide]
1066     lappend res [TestOp % $neg    $wide]
1067     lappend res [TestOp % $wide  $small]
1068     set res
1069 } [list   4068119104883679098115293636215358685 \
1070                                  12345678912345 \
1071          12135435435354435435342411603084955531 \
1072                                               5 \
1073          12135435435354435435342423948763867871 \
1074                                               5 \
1075                                  12345678912340 \
1076                                               0 \
1077           ]
1078 test mathop-24.3 { binary ops, bad values } {
1079     set res {}
1080     set exp {}
1081     foreach op {% << >>} {
1082         lappend res [TestOp $op x 1]
1083         lappend exp "can't use non-numeric string as operand of \"$op\" ARITH DOMAIN {non-numeric string}"
1084         lappend res [TestOp $op 1 x]
1085         lappend exp "can't use non-numeric string as operand of \"$op\" ARITH DOMAIN {non-numeric string}"
1086     }
1087     foreach op {% << >>} {
1088         lappend res [TestOp $op 5.0 1]
1089         lappend exp "can't use floating-point value as operand of \"$op\" ARITH DOMAIN {floating-point value}"
1090         lappend res [TestOp $op 1 5.0]
1091         lappend exp "can't use floating-point value as operand of \"$op\" ARITH DOMAIN {floating-point value}"
1092     }
1093     foreach op {in ni} {
1094         lappend res [TestOp $op 5 "a b \{ c"]
1095         lappend exp "unmatched open brace in list TCL VALUE LIST BRACE"
1096     }
1097     lappend res [TestOp % 5 0]
1098     lappend exp "divide by zero ARITH DIVZERO {divide by zero}"
1099     lappend res [TestOp % 9838923468297346238478737647637375 0]
1100     lappend exp "divide by zero ARITH DIVZERO {divide by zero}"
1101     lappend res [TestOp / 5 0]
1102     lappend exp "divide by zero ARITH DIVZERO {divide by zero}"
1103     lappend res [TestOp / 9838923468297346238478737647637375 0]
1104     lappend exp "divide by zero ARITH DIVZERO {divide by zero}"
1105     expr {$res eq $exp ? 0 : $res}
1106 } 0
1107 test mathop-24.4 { binary ops, negative shift } {
1108     set res {}
1109
1110     set big      -12135435435354435435342423948763867876
1111     set wide                             -12345678912345
1112     set small                                         -1
1113
1114     lappend res [TestOp << 10 $big]
1115     lappend res [TestOp << 10 $wide]
1116     lappend res [TestOp << 10 $small]
1117     lappend res [TestOp >> 10 $big]
1118     lappend res [TestOp >> 10 $wide]
1119     lappend res [TestOp >> 10 $small]
1120
1121     set exp [lrepeat 6 "negative shift argument NONE"]
1122     expr {$res eq $exp ? 0 : $res}
1123 } 0
1124 test mathop-24.5 { binary ops, large shift } {
1125     set res {}
1126     set exp {}
1127
1128     set big      12135435435354435435342423948763867876
1129     set wide                             12345678912345
1130     set small                                         1
1131
1132     lappend res [TestOp << 1 2147483648]
1133     lappend exp "integer value too large to represent NONE"
1134     lappend res [TestOp << 1 4294967296]
1135     lappend exp "integer value too large to represent NONE"
1136     lappend res [TestOp << $small $wide]
1137     lappend exp "integer value too large to represent NONE"
1138     lappend res [TestOp << $small $big]
1139     lappend exp "integer value too large to represent NONE"
1140     lappend res [TestOp >> $big $wide]
1141     lappend exp 0
1142     lappend res [TestOp >> $big $big]
1143     lappend exp 0
1144     lappend res [TestOp >> $small 70]
1145     lappend exp 0
1146     lappend res [TestOp >> $wide 70]
1147     lappend exp 0
1148     lappend res [TestOp >> -$big $wide]
1149     lappend exp -1
1150     lappend res [TestOp >> -$wide $wide]
1151     lappend exp -1
1152     lappend res [TestOp >> -$small $wide]
1153     lappend exp -1
1154     lappend res [TestOp >> -$small 70]
1155     lappend exp -1
1156     lappend res [TestOp >> -$wide 70]
1157     lappend exp -1
1158
1159     expr {$res eq $exp ? 0 : $res}
1160 } 0
1161 test mathop-24.6 { binary ops, shift } {
1162     # Test different combinations to get all code paths
1163     set res {}
1164
1165     set bigbig 14372423674564535234543545248972634923869
1166     set big       12135435435354435435342423948763867876
1167     set wide                              12345678912345
1168     set negwide                          -12345678912345
1169     set small                                          5
1170     set neg                                           -5
1171
1172     lappend res [TestOp << $wide $small]
1173     lappend res [TestOp >> $wide $small]
1174     set res
1175 } [list   395061725195040 \
1176              385802466010 \
1177           ]
1178 test mathop-24.7 { binary ops, list search } {
1179     set res {}
1180
1181     foreach op {in ni} {
1182         lappend res [TestOp $op 5 {7 5 8}]
1183         lappend res [TestOp $op hej {foo bar hej}]
1184         lappend res [TestOp $op 5 {7 0x5 8}]
1185     }
1186     set res
1187 } [list 1 1 0  0 0 1]
1188 test mathop-24.8 { binary ops, too many } {
1189     set exp {}
1190     foreach op {<< >> % != ne in ni ~ !} {
1191         set res [TestOp $op 7 8 9]
1192         if {[string match "wrong # args: should be * TCL WRONGARGS" $res]} {
1193             lappend exp 0
1194         } else {
1195             lappend exp $res
1196         }
1197     }
1198     set exp
1199 } {0 0 0 0 0 0 0 0 0}
1200
1201 test mathop-25.1  { exp operator } {TestOp **        } 1
1202 test mathop-25.2  { exp operator } {TestOp **   0    } 0
1203 test mathop-25.3  { exp operator } {TestOp **   0   5} 0
1204 test mathop-25.4  { exp operator } {TestOp ** 7.5    } 7.5
1205 test mathop-25.5  { exp operator } {TestOp **   1   5} 1
1206 test mathop-25.6  { exp operator } {TestOp **   5   1} 5
1207 test mathop-25.7  { exp operator } {TestOp ** 4 3 2 1} 262144
1208 test mathop-25.8  { exp operator } {TestOp ** 5.5   4} 915.0625
1209 test mathop-25.8a { exp operator } {TestOp ** 4.0  -1} 0.25
1210 test mathop-25.8b { exp operator } {TestOp ** 2.0  -2} 0.25
1211 test mathop-25.9  { exp operator } {TestOp **  16 3.5} 16384.0
1212 test mathop-25.10 { exp operator } {TestOp ** 3.5   0} 1.0
1213 test mathop-25.11 { exp operator } {TestOp ** 378   0} 1
1214 test mathop-25.12 { exp operator } {TestOp ** 7.8   1} 7.8
1215 test mathop-25.13 { exp operator } {TestOp ** 748   1} 748
1216 test mathop-25.14 { exp operator } {TestOp ** 1.6  -1} 0.625
1217 test mathop-25.15 { exp operator } {TestOp ** 683  -1} 0
1218 test mathop-25.16 { exp operator } {TestOp **   1  -1} 1
1219 test mathop-25.17 { exp operator } {TestOp **  -1  -1} -1
1220 test mathop-25.18 { exp operator } {TestOp **  -1  -2} 1
1221 test mathop-25.19 { exp operator } {TestOp **  -1   3} -1
1222 test mathop-25.20 { exp operator } {TestOp **  -1   4} 1
1223 test mathop-25.21 { exp operator } {TestOp **   2  63} 9223372036854775808
1224 test mathop-25.22 { exp operator } {TestOp **   2 256} 115792089237316195423570985008687907853269984665640564039457584007913129639936
1225 set big 83756485763458746358734658473567847567473
1226 test mathop-25.23 { exp operator } {TestOp ** $big  2} 7015148907444467657897585474493757781161998914521537835809623408157343003287605729
1227 test mathop-25.24 { exp operator } {TestOp ** $big  0} 1
1228 test mathop-25.25 { exp operator } {TestOp ** $big  1} $big
1229 test mathop-25.26 { exp operator } {TestOp ** $big -1} 0
1230 test mathop-25.27 { exp operator } {TestOp ** $big -2} 0
1231 test mathop-25.28 { exp operator } {TestOp ** $big -$big} 0
1232 test mathop-25.29 { exp operator } {expr {[set res [TestOp **  $big -1.0]]   >  0 && $res < 1.2e-41}} 1
1233 test mathop-25.30 { exp operator } {expr {[set res [TestOp **  $big -1e-18]] >  0 && $res < 1}} 1
1234 test mathop-25.31 { exp operator } {expr {[set res [TestOp ** -$big -1.0]]   > -1 && $res < 0}} 1
1235 test mathop-25.32 { exp operator } {expr {[set res [TestOp ** -$big -2.0]]   >  0 && $res < 1}} 1
1236 test mathop-25.33 { exp operator } {expr {[set res [TestOp ** -$big -3.0]]   > -1 && $res < 0}} 1
1237 test mathop-25.34 { exp operator } {TestOp ** $big -1e-30} 1.0
1238 test mathop-25.35 { exp operator } {TestOp ** $big -1e+30} 0.0
1239 test mathop-25.36 { exp operator } {TestOp **    0  $big}             0
1240 test mathop-25.37 { exp operator } {TestOp **    1  $big}             1
1241 test mathop-25.38 { exp operator } {TestOp **   -1  $big}            -1
1242 test mathop-25.39 { exp operator } {TestOp **   -1  [expr {$big+1}]}  1
1243 test mathop-25.40 { exp operator (small exponent power helper and its boundaries) } {
1244     set pwr 0
1245     set res 1
1246     while {[incr pwr] <= 17 && [set i [TestOp ** 15 $pwr]] == [set res [expr {$res * 15}]]} {}
1247     list [incr pwr -1] $res
1248 } {17 98526125335693359375}
1249 test mathop-25.41 { exp operator errors } {
1250     set res {}
1251     set exp {}
1252
1253     set huge     [string repeat 145782 1000]
1254     set big      12135435435354435435342423948763867876
1255     set wide                             12345678912345
1256     set small                                         2
1257
1258     lappend res [TestOp ** 0 -5]
1259     lappend exp "exponentiation of zero by negative power ARITH DOMAIN {exponentiation of zero by negative power}"
1260     lappend res [TestOp ** 0.0 -5.0]
1261     lappend exp "exponentiation of zero by negative power ARITH DOMAIN {exponentiation of zero by negative power}"
1262     lappend res [TestOp ** $small $wide]
1263     lappend exp "exponent too large NONE"
1264     lappend res [TestOp ** 2 $big]
1265     lappend exp "exponent too large NONE"
1266     lappend res [TestOp ** $huge 2.1]
1267     lappend exp "Inf"
1268     lappend res [TestOp ** 2 foo]
1269     lappend exp "can't use non-numeric string as operand of \"**\" ARITH DOMAIN {non-numeric string}"
1270     lappend res [TestOp ** foo 2]
1271     lappend exp "can't use non-numeric string as operand of \"**\" ARITH DOMAIN {non-numeric string}"
1272
1273     expr {$res eq $exp ? 0 : $res}
1274 } 0
1275
1276 test mathop-26.1 { misc ops, size combinations } {
1277     set big1      12135435435354435435342423948763867876
1278     set big2       2746237174783836746262564892918327847
1279     set wide1                             87321847232215
1280     set wide2                             12345678912345
1281     set small1                                     87345
1282     set small2                                     16753
1283
1284     set res {}
1285     foreach op {+ * - /} {
1286         lappend res [TestOp $op $big1   $big2]
1287         lappend res [TestOp $op $big1   $wide2]
1288         lappend res [TestOp $op $big1   $small2]
1289         lappend res [TestOp $op $wide1  $big2]
1290         lappend res [TestOp $op $wide1  $wide2]
1291         lappend res [TestOp $op $wide1  $small2]
1292         lappend res [TestOp $op $small1 $big2]
1293         lappend res [TestOp $op $small1 $wide2]
1294         lappend res [TestOp $op $small1 $small2]
1295     }
1296     set res
1297 } [list \
1298            14881672610138272181604988841682195723 \
1299            12135435435354435435342436294442780221 \
1300            12135435435354435435342423948763884629 \
1301            2746237174783836746262652214765560062 \
1302            99667526144560 \
1303            87321847248968 \
1304            2746237174783836746262564892918415192 \
1305            12345678999690 \
1306            104098 \
1307            33326783924759424684447891401270222910405366244661685890993770489959542972 \
1308            149820189346379518024969783068410988366610965329220 \
1309            203304949848492856848291628413641078526628 \
1310            239806503039903915972546163440347114360602909991105 \
1311            1078047487961768329845194175 \
1312            1462902906681297895 \
1313            239870086031494220602303730571951345796215 \
1314            1078333324598774025 \
1315            1463290785 \
1316            9389198260570598689079859055845540029 \
1317            12135435435354435435342411603084955531 \
1318            12135435435354435435342423948763851123 \
1319            -2746237174783836746262477571071095632 \
1320            74976168319870 \
1321            87321847215462 \
1322            -2746237174783836746262564892918240502 \
1323            -12345678825000 \
1324            70592 \
1325            4 \
1326            982970278225822587257201 \
1327            724373869477373332259441529801460 \
1328            0 \
1329            7 \
1330            5212311062 \
1331            0 \
1332            0 \
1333            5 \
1334           ]
1335 test mathop-26.2 { misc ops, corner cases } {
1336     set res {}
1337     lappend res [TestOp - 0 -2147483648]                  ;# -2**31
1338     lappend res [TestOp - 0 -9223372036854775808]         ;# -2**63
1339     lappend res [TestOp / -9223372036854775808 -1]
1340     lappend res [TestOp * 2147483648 2]
1341     lappend res [TestOp * 9223372036854775808 2]
1342     set res
1343 } [list 2147483648 9223372036854775808 9223372036854775808 4294967296 18446744073709551616]
1344
1345 if 0 {
1346     # Compare ops to expr bytecodes
1347     namespace import ::tcl::mathop::*
1348     proc _X {a b c} {
1349         set x [+ $a [- $b $c]]
1350         set y [expr {$a + ($b - $c)}]
1351         set z [< $a $b $c]
1352     }
1353     set ::tcl_traceCompile 2
1354     _X 3 4 5
1355     set ::tcl_traceCompile 0
1356 }
1357
1358 # cleanup
1359 namespace delete ::testmathop
1360 namespace delete ::testmathop2
1361 ::tcltest::cleanupTests
1362 return
1363
1364 # Local Variables:
1365 # mode: tcl
1366 # End: