Check-in [5e48c91234]
Not logged in

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:implementation for TIP #255, expr min/max
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 5e48c91234ebf451dfa90025b351b78b47cf3560
User & Date: hobbs 2005-09-29 23:16:29.000
Context
2005-09-30
01:05
init value to (-)Inf for min/max expr functions to simplify code check-in: 78d70230d5 user: hobbs tags: trunk
2005-09-29
23:16
implementation for TIP #255, expr min/max check-in: 5e48c91234 user: hobbs tags: trunk
2005-09-27
15:35
Test for [Bug 1116542] check-in: d7a27184e4 user: dkf tags: trunk
Changes
Unified Diff Ignore Whitespace Patch
Changes to ChangeLog.






1
2
3
4
5
6
7






2005-09-27  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>

	* tests/binary.test (binary-14.18): Added test for [Bug 1116542]
	though the bug itself was already fixed by unrelated changes.

2005-09-26  Kevin Kenny  <kennykb@acm.org>

>
>
>
>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
2005-09-29  Jeff Hobbs  <jeffh@ActiveState.com>

	* doc/mathfunc.n:   implementation for TIP #255, expr min/max
	* library/init.tcl:
	* tests/info.test, tests/expr-old.test: 

2005-09-27  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>

	* tests/binary.test (binary-14.18): Added test for [Bug 1116542]
	though the bug itself was already fixed by unrelated changes.

2005-09-26  Kevin Kenny  <kennykb@acm.org>

Changes to doc/mathfunc.n.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-2000 Sun Microsystems, Inc.
'\" Copyright (c) 2005 by Kevin B. Kenny <kennykb@acm.org>. All rights reserved
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" RCS: @(#) $Id: mathfunc.n,v 1.6 2005/06/09 14:24:06 dkf Exp $
'\" 
.so man.macros
.TH mathfunc n 8.5 Tcl "Tcl Mathematical Functions"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
mathfunc \- Mathematical functions for Tcl expressions








|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-2000 Sun Microsystems, Inc.
'\" Copyright (c) 2005 by Kevin B. Kenny <kennykb@acm.org>. All rights reserved
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" RCS: @(#) $Id: mathfunc.n,v 1.7 2005/09/29 23:16:29 hobbs Exp $
'\" 
.so man.macros
.TH mathfunc n 8.5 Tcl "Tcl Mathematical Functions"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
mathfunc \- Mathematical functions for Tcl expressions
47
48
49
50
51
52
53




54
55
56
57
58
59
60
.br
\fB::tcl::mathfunc::int\fR \fIarg\fR
.br
\fB::tcl::mathfunc::log\fR \fIarg\fR
.br
\fB::tcl::mathfunc::log10\fR \fIarg\fR
.br




\fB::tcl::mathfunc::pow\fR \fIx\fR \fIy\fR
.br
\fB::tcl::mathfunc::rand\fR
.br
\fB::tcl::mathfunc::round\fR \fIarg\fR
.br
\fB::tcl::mathfunc::sin\fR \fIarg\fR







>
>
>
>







47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
.br
\fB::tcl::mathfunc::int\fR \fIarg\fR
.br
\fB::tcl::mathfunc::log\fR \fIarg\fR
.br
\fB::tcl::mathfunc::log10\fR \fIarg\fR
.br
\fB::tcl::mathfunc::max\fR \fIarg\fR ?\fIarg\fR ...?
.br
\fB::tcl::mathfunc::min\fR \fIarg\fR ?\fIarg\fR ...?
.br
\fB::tcl::mathfunc::pow\fR \fIx\fR \fIy\fR
.br
\fB::tcl::mathfunc::rand\fR
.br
\fB::tcl::mathfunc::round\fR \fIarg\fR
.br
\fB::tcl::mathfunc::sin\fR \fIarg\fR
83
84
85
86
87
88
89
90
91
92
93
94
95
96

97
98
99
100
101
102
103
for code apart from \fBexpr\fR, by invoking the given commands
directly.
.PP
Tcl supports the following mathematical functions in expressions, all
of which work solely with floating-point numbers unless otherwise noted:
.DS
.ta 3c 6c 9c
\fBabs\fR	\fBcos\fR	\fBint\fR	\fBsinh\fR
\fBacos\fR	\fBcosh\fR	\fBlog\fR	\fBsqrt\fR
\fBasin\fR	\fBdouble\fR	\fBlog10\fR	\fBsrand\fR
\fBatan\fR	\fBexp\fR	\fBpow\fR	\fBtan\fR
\fBatan2\fR	\fBfloor\fR	\fBrand\fR	\fBtanh\fR
\fBbool\fR	\fBfmod\fR	\fBround\fR	\fBwide\fR
\fBceil\fR	\fBhypot\fR	\fBsin\fR

.DE
.PP
.TP
\fBabs(\fIarg\fB)\fR
Returns the absolute value of \fIarg\fR.  \fIArg\fR may be either
integer or floating-point, and the result is returned in the same form.
.TP







|
|
|
|
|
|
|
>







87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
for code apart from \fBexpr\fR, by invoking the given commands
directly.
.PP
Tcl supports the following mathematical functions in expressions, all
of which work solely with floating-point numbers unless otherwise noted:
.DS
.ta 3c 6c 9c
\fBabs\fR	\fBacos\fR	\fBasin\fR	\fBatan\fR
\fBatan2\fR	\fBbool\fR	\fBceil\fR	\fBcos\fR
\fBcosh\fR	\fBdouble\fR	\fBexp\fR	\fBfloor\fR
\fBfmod\fR	\fBhypot\fR	\fBint\fR	\fBlog\fR
\fBlog10\fR	\fBmax\fR	\fBmin\fR	\fBpow\fR
\fBrand\fR	\fBround\fR	\fBsin\fR	\fBsinh\fR
\fBsqrt\fR	\fBsrand\fR	\fBtan\fR	\fBtanh\fR
\fBwide\fR
.DE
.PP
.TP
\fBabs(\fIarg\fB)\fR
Returns the absolute value of \fIarg\fR.  \fIArg\fR may be either
integer or floating-point, and the result is returned in the same form.
.TP
167
168
169
170
171
172
173






174
175
176
177
178
179
180
Returns the natural logarithm of \fIarg\fR.  \fIArg\fR must be a
positive value.
.TP
\fBlog10(\fIarg\fB)\fR
Returns the base 10 logarithm of \fIarg\fR.  \fIArg\fR must be a
positive value.
.TP






\fBpow(\fIx, y\fB)\fR
Computes the value of \fIx\fR raised to the power \fIy\fR.  If \fIx\fR
is negative, \fIy\fR must be an integer value.
.TP
\fBrand()\fR
Returns a pseudo-random floating-point value in the range (\fI0\fR,\fI1\fR).  
The generator algorithm is a simple linear congruential generator that







>
>
>
>
>
>







172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
Returns the natural logarithm of \fIarg\fR.  \fIArg\fR must be a
positive value.
.TP
\fBlog10(\fIarg\fB)\fR
Returns the base 10 logarithm of \fIarg\fR.  \fIArg\fR must be a
positive value.
.TP
\fBmax(\fIarg\fB, \fI...\fB)\fR
Returns the maximum value of all given numeric arguments.
.TP
\fBmin(\fIarg\fB, \fI...\fB)\fR
Returns the minimum value of all given numeric arguments.
.TP
\fBpow(\fIx, y\fB)\fR
Computes the value of \fIx\fR raised to the power \fIy\fR.  If \fIx\fR
is negative, \fIy\fR must be an integer value.
.TP
\fBrand()\fR
Returns a pseudo-random floating-point value in the range (\fI0\fR,\fI1\fR).  
The generator algorithm is a simple linear congruential generator that
Changes to library/init.tcl.
1
2
3
4
5
6
7
8
9
10
11
12
13
# init.tcl --
#
# Default system startup file for Tcl-based applications.  Defines
# "unknown" procedure and auto-load facilities.
#
# RCS: @(#) $Id: init.tcl,v 1.81 2005/09/14 17:13:18 dgp Exp $
#
# Copyright (c) 1991-1993 The Regents of the University of California.
# Copyright (c) 1994-1996 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 Scriptics Corporation.
# Copyright (c) 2004 by Kevin B. Kenny.  All rights reserved.
#
# See the file "license.terms" for information on usage and redistribution





|







1
2
3
4
5
6
7
8
9
10
11
12
13
# init.tcl --
#
# Default system startup file for Tcl-based applications.  Defines
# "unknown" procedure and auto-load facilities.
#
# RCS: @(#) $Id: init.tcl,v 1.82 2005/09/29 23:16:29 hobbs Exp $
#
# Copyright (c) 1991-1993 The Regents of the University of California.
# Copyright (c) 1994-1996 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 Scriptics Corporation.
# Copyright (c) 2004 by Kevin B. Kenny.  All rights reserved.
#
# See the file "license.terms" for information on usage and redistribution
91
92
93
94
95
96
97










































98
99
100
101
102
103
104
            puts        ::puts
            read        ::read
            seek        ::seek
            tell        ::tell
            truncate    ::tcl::chan::Truncate
        }
    }










































}

# Windows specific end of initialization

if {(![interp issafe]) && ($tcl_platform(platform) eq "windows")} {
    namespace eval tcl {
	proc EnvTraceProc {lo n1 n2 op} {







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
            puts        ::puts
            read        ::read
            seek        ::seek
            tell        ::tell
            truncate    ::tcl::chan::Truncate
        }
    }

    # TIP #255 min and max functions
    namespace eval mathfunc {
	proc min {args} {
	    if {[llength $args] == 0} {
		return -code error \
		    "too few arguments to math function \"min\""
	    }
	    set val [lindex $args 0]
	    # This will handle forcing the numeric value without
	    # ruining the interval type of a numeric object
	    if {[catch {expr {double($val)}} err]} {
		return -code error $err
	    }
	    foreach arg [lrange $args 1 end] {
		if {[catch {expr {double($arg)}} err]} {
		    return -code error $err
		}
		if {$arg < $val} { set val $arg }
	    }
	    return $val
	}
	proc max {args} {
	    if {[llength $args] == 0} {
		return -code error \
		    "too few arguments to math function \"max\""
	    }
	    set val [lindex $args 0]
	    # This will handle forcing the numeric value without
	    # ruining the interval type of a numeric object
	    if {[catch {expr {double($val)}} err]} {
		return -code error $err
	    }
	    foreach arg [lrange $args 1 end] {
		if {[catch {expr {double($arg)}} err]} {
		    return -code error $err
		}
		if {$arg > $val} { set val $arg }
	    }
	    return $val
	}
    }
}

# Windows specific end of initialization

if {(![interp issafe]) && ($tcl_platform(platform) eq "windows")} {
    namespace eval tcl {
	proc EnvTraceProc {lo n1 n2 op} {
Changes to tests/expr-old.test.
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# Copyright (c) 1991-1994 The Regents of the University of California.
# Copyright (c) 1994-1997 Sun Microsystems, Inc.
# Copyright (c) 1998-2000 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-old.test,v 1.26 2005/07/28 18:42:28 dgp Exp $

if {[lsearch [namespace children] ::tcltest] == -1} {
    package require tcltest 2.1
    namespace import -force ::tcltest::*
}

if {([catch {expr T1()} msg] == 1) && ($msg == {unknown math function "T1"})} {







|







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# Copyright (c) 1991-1994 The Regents of the University of California.
# Copyright (c) 1994-1997 Sun Microsystems, Inc.
# Copyright (c) 1998-2000 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-old.test,v 1.27 2005/09/29 23:16:29 hobbs Exp $

if {[lsearch [namespace children] ::tcltest] == -1} {
    package require tcltest 2.1
    namespace import -force ::tcltest::*
}

if {([catch {expr T1()} msg] == 1) && ($msg == {unknown math function "T1"})} {
1051
1052
1053
1054
1055
1056
1057










































1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
    catch {
	set x [list [expr {$x == round($y)}] [expr $x == -round(-$y)]]
    }
    set x
} {1 1}
unset -nocomplain x y











































# Special test for Pentium arithmetic bug of 1994:

if {(4195835.0 - (4195835.0/3145727.0)*3145727.0) == 256.0} {
    puts "Warning: this machine contains a defective Pentium processor"
    puts "that performs arithmetic incorrectly.  I recommend that you"
    puts "call Intel customer service immediately at 1-800-628-8686"
    puts "to request a replacement processor."
}

# cleanup
::tcltest::cleanupTests
return







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>












1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
    catch {
	set x [list [expr {$x == round($y)}] [expr $x == -round(-$y)]]
    }
    set x
} {1 1}
unset -nocomplain x y

#
# TIP #255 min and max math functions
#

test expr-old-40.1 {min math function} -body {
    expr {min(0)}
} -result 0
test expr-old-40.2 {min math function} -body {
    expr {min(0.0)}
} -result 0.0
test expr-old-40.3 {min math function} -body {
    list [catch {expr {min()}} msg] $msg
} -result {1 {too few arguments to math function "min"}}
test expr-old-40.4 {min math function} -body {
    expr {min(wide(-1) << 30, 4.5, -10)}
} -result [expr {wide(-1) << 30}]
test expr-old-40.5 {min math function} -body {
    list [catch {expr {min("a", 0)}} msg] $msg
} -result {1 {argument to math function didn't have numeric value}}
test expr-old-40.6 {min math function} -body {
    expr {min(300, "0xFF")}
} -result 255

test expr-old-41.1 {max math function} -body {
    expr {max(0)}
} -result 0
test expr-old-41.2 {max math function} -body {
    expr {max(0.0)}
} -result 0.0
test expr-old-41.3 {max math function} -body {
    list [catch {expr {max()}} msg] $msg
} -result {1 {too few arguments to math function "max"}}
test expr-old-41.4 {max math function} -body {
    expr {max(wide(1) << 30, 4.5, -10)}
} -result [expr {wide(1) << 30}]
test expr-old-41.5 {max math function} -body {
    list [catch {expr {max("a", 0)}} msg] $msg
} -result {1 {argument to math function didn't have numeric value}}
test expr-old-41.6 {max math function} -body {
    expr {max(200, "0xFF")}
} -result 255

# Special test for Pentium arithmetic bug of 1994:

if {(4195835.0 - (4195835.0/3145727.0)*3145727.0) == 256.0} {
    puts "Warning: this machine contains a defective Pentium processor"
    puts "that performs arithmetic incorrectly.  I recommend that you"
    puts "call Intel customer service immediately at 1-800-628-8686"
    puts "to request a replacement processor."
}

# cleanup
::tcltest::cleanupTests
return
Changes to tests/info.test.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# Commands covered:  info
#
# 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) 1991-1994 The Regents of the University of California.
# Copyright (c) 1994-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: info.test,v 1.32 2005/07/29 14:47:47 dkf Exp $

if {[lsearch [namespace children] ::tcltest] == -1} {
    package require tcltest 2
    namespace import -force ::tcltest::*
}

# Set up namespaces needed to test operation of "info args", "info body",













|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# Commands covered:  info
#
# 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) 1991-1994 The Regents of the University of California.
# Copyright (c) 1994-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: info.test,v 1.33 2005/09/29 23:16:29 hobbs Exp $

if {[lsearch [namespace children] ::tcltest] == -1} {
    package require tcltest 2
    namespace import -force ::tcltest::*
}

# Set up namespaces needed to test operation of "info args", "info body",
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
    namespace eval x info vars foo
} -cleanup {
    namespace delete x
} -result {}

# Check whether the extra testing functions are defined...
if {([catch {expr T1()} msg] == 1) && ($msg == {unknown math function "T1"})} {
    set functions {abs acos asin atan atan2 bool ceil cos cosh double exp floor fmod hypot int log log10 pow rand round sin sinh sqrt srand tan tanh wide}
} else {
    set functions {T1 T2 T3 abs acos asin atan atan2 bool ceil cos cosh double exp floor fmod hypot int log log10 pow rand round sin sinh sqrt srand tan tanh wide}
}
test info-20.1 {info functions option} {info functions sin} sin
test info-20.2 {info functions option} {lsort [info functions]} $functions
test info-20.3 {info functions option} {
    lsort [info functions a*]
} {abs acos asin atan atan2}
test info-20.4 {info functions option} {







|

|







623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
    namespace eval x info vars foo
} -cleanup {
    namespace delete x
} -result {}

# Check whether the extra testing functions are defined...
if {([catch {expr T1()} msg] == 1) && ($msg == {unknown math function "T1"})} {
    set functions {abs acos asin atan atan2 bool ceil cos cosh double exp floor fmod hypot int log log10 max min pow rand round sin sinh sqrt srand tan tanh wide}
} else {
    set functions {T1 T2 T3 abs acos asin atan atan2 bool ceil cos cosh double exp floor fmod hypot int log log10 max min pow rand round sin sinh sqrt srand tan tanh wide}
}
test info-20.1 {info functions option} {info functions sin} sin
test info-20.2 {info functions option} {lsort [info functions]} $functions
test info-20.3 {info functions option} {
    lsort [info functions a*]
} {abs acos asin atan atan2}
test info-20.4 {info functions option} {