diff options
Diffstat (limited to 'doc/expr.n')
| -rw-r--r-- | doc/expr.n | 417 |
1 files changed, 219 insertions, 198 deletions
@@ -1,14 +1,13 @@ '\" '\" 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: expr.n,v 1.5 2000/09/07 14:27:47 poenitz Exp $ -'\" +.TH expr n 8.5 Tcl "Tcl Built-In Commands" .so man.macros -.TH expr n 8.4 Tcl "Tcl Built-In Commands" .BS '\" Note: do not modify the .SH NAME line immediately below! .SH NAME @@ -16,14 +15,14 @@ expr \- Evaluate an expression .SH SYNOPSIS \fBexpr \fIarg \fR?\fIarg arg ...\fR? .BE - .SH DESCRIPTION .PP -Concatenates \fIarg\fR's (adding separator spaces between them), +Concatenates \fIarg\fRs (adding separator spaces between them), evaluates the result as a Tcl expression, and returns the value. -The operators permitted in Tcl expressions are a subset of -the operators permitted in C expressions, and they have the -same meaning and precedence as the corresponding C operators. +The operators permitted in Tcl expressions include a subset of +the operators permitted in C expressions. For those operators +common to both Tcl and C, Tcl applies the same meaning and precedence +as the corresponding C operators. Expressions almost always yield numeric results (integer or floating-point values). For example, the expression @@ -33,57 +32,68 @@ For example, the expression evaluates to 14.2. Tcl expressions differ from C expressions in the way that operands are specified. Also, Tcl expressions support -non-numeric operands and string comparisons. -.SH OPERANDS +non-numeric operands and string comparisons, as well as some +additional operators not found in C. +.SS OPERANDS .PP A Tcl expression consists of a combination of operands, operators, and parentheses. White space may be used between the operands and operators and parentheses; it is ignored by the expression's instructions. Where possible, operands are interpreted as integer values. -Integer values may be specified in decimal (the normal case), in octal (if the -first character of the operand is \fB0\fR), or in hexadecimal (if the first -two characters of the operand are \fB0x\fR). +.VS 8.5 +Integer values may be specified in decimal (the normal case), in binary +(if the first two characters of the operand are \fB0b\fR), in octal +(if the first two characters of the operand are \fB0o\fR), or in hexadecimal +(if the first two characters of the operand are \fB0x\fR). For +compatibility with older Tcl releases, an octal integer value is also +indicated simply when the first character of the operand is \fB0\fR, +whether or not the second character is also \fBo\fR. If an operand does not have one of the integer formats given above, then it is treated as a floating-point number if that is -possible. Floating-point numbers may be specified in any of the -ways accepted by an ANSI-compliant C compiler (except that the -\fBf\fR, \fBF\fR, \fBl\fR, and \fBL\fR suffixes will not be permitted in -most installations). For example, all of the +possible. Floating-point numbers may be specified in any of several +common formats making use of the decimal digits, the decimal point \fB.\fR, +the characters \fBe\fR or \fBE\fR indicating scientific notation, and +the sign characters \fB+\fR or \fB\-\fR. For example, all of the following are valid floating-point numbers: 2.1, 3., 6e4, 7.91e+16. -If no numeric interpretation is possible, then an operand is left -as a string (and only a limited set of operators may be applied to -it). +Also recognized as floating point values are the strings \fBInf\fR +and \fBNaN\fR making use of any case for each character. +.VE 8.5 +If no numeric interpretation is possible (note that all literal +operands that are not numeric or boolean must be quoted with either +braces or with double quotes), then an operand is left as a string +(and only a limited set of operators may be applied to it). .PP Operands may be specified in any of the following ways: .IP [1] -As an numeric value, either integer or floating-point. +As a numeric value, either integer or floating-point. .IP [2] +As a boolean value, using any form understood by \fBstring is boolean\fR. +.IP [3] As a Tcl variable, using standard \fB$\fR notation. The variable's value will be used as the operand. -.IP [3] +.IP [4] As a string enclosed in double-quotes. The expression parser will perform backslash, variable, and command substitutions on the information between the quotes, and use the resulting value as the operand -.IP [4] +.IP [5] As a string enclosed in braces. The characters between the open brace and matching close brace will be used as the operand without any substitutions. -.IP [5] +.IP [6] As a Tcl command enclosed in brackets. The command will be executed and its result will be used as the operand. -.IP [6] +.IP [7] As a mathematical function whose arguments have any of the above -forms for operands, such as \fBsin($x)\fR. See below for a list of defined -functions. +forms for operands, such as \fBsin($x)\fR. See \fBMATH FUNCTIONS\fR below for +a discussion of how mathematical functions are handled. .LP -Where substitutions occur above (e.g. inside quoted strings), they +Where the above substitutions occur (e.g. inside quoted strings), they are performed by the expression's instructions. -However, an additional layer of substitution may already have -been performed by the command parser before the expression -processor was called. +However, the command parser may already have performed one round of +substitution before the expression processor was called. As discussed below, it is usually best to enclose expressions in braces to prevent the command parser from performing substitutions on the contents. @@ -95,27 +105,46 @@ Then the command on the left side of each of the lines below will produce the value on the right side of the line: .CS .ta 6c -\fBexpr 3.1 + $a 6.1 -expr 2 + "$a.$b" 5.6 -expr 4*[llength "6 2"] 8 -expr {{word one} < "word $a"} 0\fR +\fBexpr\fR 3.1 + $a \fI6.1\fR +\fBexpr\fR 2 + "$a.$b" \fI5.6\fR +\fBexpr\fR 4*[llength "6 2"] \fI8\fR +\fBexpr\fR {{word one} < "word $a"} \fI0\fR .CE -.SH OPERATORS +.SS OPERATORS .PP -The valid operators are listed below, grouped in decreasing order -of precedence: +The valid operators (most of which are also available as commands in +the \fBtcl::mathop\fR namespace; see the \fBmathop\fR(n) manual page +for details) are listed below, grouped in decreasing order of precedence: .TP 20 \fB\-\0\0+\0\0~\0\0!\fR -Unary minus, unary plus, bit-wise NOT, logical NOT. None of these operands +Unary minus, unary plus, bit-wise NOT, logical NOT. None of these operators may be applied to string operands, and bit-wise NOT may be applied only to integers. .TP 20 +\fB**\fR +.VS 8.5 +Exponentiation. Valid for any numeric operands. +.VE 8.5 +.TP 20 \fB*\0\0/\0\0%\fR -Multiply, divide, remainder. None of these operands may be +Multiply, divide, remainder. None of these operators may be applied to string operands, and remainder may be applied only to integers. The remainder will always have the same sign as the divisor and -an absolute value smaller than the divisor. +an absolute value smaller than the absolute value of the divisor. +.RS +.PP +When applied to integers, the division and remainder operators can be +considered to partition the number line into a sequence of equal-sized +adjacent non-overlapping pieces where each piece is the size of the divisor; +the division result identifies which piece the divisor lay within, and the +remainder result identifies where within that piece the divisor lay. A +consequence of this is that the result of +.QW "-57 \fB/\fR 10" +is always -6, and the result of +.QW "-57 \fB%\fR 10" +is always 3. +.RE .TP 20 \fB+\0\0\-\fR Add and subtract. Valid for any numeric operands. @@ -133,12 +162,19 @@ in which case string comparison is used. \fB==\0\0!=\fR Boolean equal and not equal. Each operator produces a zero/one result. Valid for all operand types. -.VS 8.4 .TP 20 \fBeq\0\0ne\fR Boolean string equal and string not equal. Each operator produces a zero/one result. The operand types are interpreted only as strings. -.VE 8.4 +.TP 20 +\fBin\0\0ni\fR +.VS 8.5 +List containment and negated list containment. Each operator produces +a zero/one result and treats its first argument as a string and its +second argument as a Tcl list. The \fBin\fR operator indicates +whether the first argument is a member of the second argument list; +the \fBni\fR operator inverts the sense of the result. +.VE 8.5 .TP 20 \fB&\fR Bit-wise AND. Valid for integer operands only. @@ -162,153 +198,88 @@ Valid for boolean and numeric (integers or floating-point) operands only. If-then-else, as in C. If \fIx\fR evaluates to non-zero, then the result is the value of \fIy\fR. Otherwise the result is the value of \fIz\fR. -The \fIx\fR operand must have a numeric value. +The \fIx\fR operand must have a boolean or numeric value. .LP See the C manual for more details on the results produced by each operator. +.VS 8.5 +The exponentiation operator promotes types like the multiply and +divide operators, and produces a result that is the same as the output +of the \fBpow\fR function (after any type conversions.) +.VE 8.5 All of the binary operators group left-to-right within the same precedence level. For example, the command .CS -\fBexpr 4*2 < 7\fR +\fBexpr\fR {4*2 < 7} .CE returns 0. .PP -The \fB&&\fR, \fB||\fR, and \fB?:\fR operators have ``lazy -evaluation'', just as in C, -which means that operands are not evaluated if they are +The \fB&&\fR, \fB||\fR, and \fB?:\fR operators have +.QW "lazy evaluation" , +just as in C, which means that operands are not evaluated if they are not needed to determine the outcome. For example, in the command .CS \fBexpr {$v ? [a] : [b]}\fR .CE -only one of \fB[a]\fR or \fB[b]\fR will actually be evaluated, +only one of +.QW \fB[a]\fR +or +.QW \fB[b]\fR +will actually be evaluated, depending on the value of \fB$v\fR. Note, however, that this is only true if the entire expression is enclosed in braces; otherwise -the Tcl parser will evaluate both \fB[a]\fR and \fB[b]\fR before -invoking the \fBexpr\fR command. -.SH "MATH FUNCTIONS" +the Tcl parser will evaluate both +.QW \fB[a]\fR +and +.QW \fB[b]\fR +before invoking the \fBexpr\fR command. +.SS "MATH FUNCTIONS" +.PP +.VS 8.5 +When the expression parser encounters a mathematical function +such as \fBsin($x)\fR, it replaces it with a call to an ordinary +Tcl function in the \fBtcl::mathfunc\fR namespace. The processing +of an expression such as: +.CS +\fBexpr {sin($x+$y)}\fR +.CE +is the same in every way as the processing of: +.CS +\fBexpr {[tcl::mathfunc::sin [expr {$x+$y}]]}\fR +.CE +which in turn is the same as the processing of: +.CS +\fBtcl::mathfunc::sin [expr {$x+$y}]\fR +.CE .PP -Tcl supports the following mathematical functions in expressions: -.DS -.ta 3c 6c 9c -\fBabs\fR \fBcosh\fR \fBlog\fR \fBsqrt\fR -\fBacos\fR \fBdouble\fR \fBlog10\fR \fBsrand\fR -\fBasin\fR \fBexp\fR \fBpow\fR \fBtan\fR -\fBatan\fR \fBfloor\fR \fBrand\fR \fBtanh\fR -\fBatan2\fR \fBfmod\fR \fBround\fR -\fBceil\fR \fBhypot\fR \fBsin\fR -\fBcos\fR \fBint\fR \fBsinh\fR -.DE +The executor will search for \fBtcl::mathfunc::sin\fR using the usual +rules for resolving functions in namespaces. Either +\fB::tcl::mathfunc::sin\fR or \fB[namespace +current]::tcl::mathfunc::sin\fR will satisfy the request, and others +may as well (depending on the current \fBnamespace path\fR setting). .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 -\fBacos(\fIarg\fB)\fR -Returns the arc cosine of \fIarg\fR, in the range [0,pi] -radians. \fIArg\fR should be in the range [-1,1]. -.TP -\fBasin(\fIarg\fB)\fR -Returns the arc sine of \fIarg\fR, in the range [-pi/2,pi/2] radians. -\fIArg\fR should be in the range [-1,1]. -.TP -\fBatan(\fIarg\fB)\fR -Returns the arc tangent of \fIarg\fR, in the range [-pi/2,pi/2] radians. -.TP -\fBatan2(\fIx, y\fB)\fR -Returns the arc tangent of \fIy\fR/\fIx\fR, in the range [-pi,pi] -radians. \fIx\fR and \fIy\fR cannot both be 0. -.TP -\fBceil(\fIarg\fB)\fR -Returns the smallest integer value not less than \fIarg\fR. -.TP -\fBcos(\fIarg\fB)\fR -Returns the cosine of \fIarg\fR, measured in radians. -.TP -\fBcosh(\fIarg\fB)\fR -Returns the hyperbolic cosine of \fIarg\fR. If the result would cause -an overflow, an error is returned. -.TP -\fBdouble(\fIarg\fB)\fR -If \fIarg\fR is a floating value, returns \fIarg\fR, otherwise converts -\fIarg\fR to floating and returns the converted value. -.TP -\fBexp(\fIarg\fB)\fR -Returns the exponential of \fIarg\fR, defined as e**\fIarg\fR. If the -result would cause an overflow, an error is returned. -.TP -\fBfloor(\fIarg\fB)\fR -Returns the largest integral value not greater than \fIarg\fR. -.TP -\fBfmod(\fIx, y\fB)\fR -Returns the floating-point remainder of the division of \fIx\fR by -\fIy\fR. If \fIy\fR is 0, an error is returned. -.TP -\fBhypot(\fIx, y\fB)\fR -Computes the length of the hypotenuse of a right-angled triangle -(\fIx\fR*\fIx\fR+\fIy\fR*\fIy\fR). -.TP -\fBint(\fIarg\fB)\fR -If \fIarg\fR is an integer value, returns \fIarg\fR, otherwise converts -\fIarg\fR to integer by truncation and returns the converted value. -.TP -\fBlog(\fIarg\fB)\fR -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 floating point number from zero to just less than one or, -in mathematical terms, the range [0,1). The seed comes from the -internal clock of the machine or may be set manual with the srand -function. -.TP -\fBround(\fIarg\fB)\fR -If \fIarg\fR is an integer value, returns \fIarg\fR, otherwise converts -\fIarg\fR to integer by rounding and returns the converted value. -.TP -\fBsin(\fIarg\fB)\fR -Returns the sine of \fIarg\fR, measured in radians. -.TP -\fBsinh(\fIarg\fB)\fR -Returns the hyperbolic sine of \fIarg\fR. If the result would cause -an overflow, an error is returned. -.TP -\fBsqrt(\fIarg\fB)\fR -Returns the square root of \fIarg\fR. \fIArg\fR must be non-negative. -.TP -\fBsrand(\fIarg\fB)\fR -The \fIarg\fR, which must be an integer, is used to reset the seed for -the random number generator. Returns the first random number from -that seed. Each interpreter has it's own seed. -.TP -\fBtan(\fIarg\fB)\fR -Returns the tangent of \fIarg\fR, measured in radians. -.TP -\fBtanh(\fIarg\fB)\fR -Returns the hyperbolic tangent of \fIarg\fR. +See the \fBmathfunc\fR(n) manual page for the math functions that are +available by default. +.VE 8.5 +.SS "TYPES, OVERFLOW, AND PRECISION" .PP -In addition to these predefined functions, applications may -define additional functions using \fBTcl_CreateMathFunc\fR(). -.SH "TYPES, OVERFLOW, AND PRECISION" +.VS 8.5 +All internal computations involving integers are done calling on the +LibTomMath multiple precision integer library as required so that all +integer calculations are performed exactly. Note that in Tcl releases +prior to 8.5, integer calculations were performed with one of the C types +\fIlong int\fR or \fITcl_WideInt\fR, causing implicit range truncation +in those calculations where values overflowed the range of those types. +Any code that relied on these implicit truncations will need to explicitly +add \fBint()\fR or \fBwide()\fR function calls to expressions at the points +where such truncation is required to take place. +.VE 8.5 .PP -All internal computations involving integers are done with the C type -\fIlong\fR, and all internal computations involving floating-point are +All internal computations involving floating-point are done with the C type \fIdouble\fR. When converting a string to floating-point, exponent overflow is -detected and results in a Tcl error. -For conversion to integer from string, detection of overflow depends -on the behavior of some routines in the local C library, so it should -be regarded as unreliable. -In any case, integer overflow and underflow are generally not detected -reliably for intermediate results. Floating-point overflow and underflow +detected and results in the \fIdouble\fR value of \fBInf\fR or +\fB\-Inf\fR as appropriate. Floating-point overflow and underflow are detected to the degree supported by the hardware, which is generally pretty reliable. .PP @@ -318,51 +289,48 @@ For arithmetic computations, integers are used until some floating-point number is introduced, after which floating-point is used. For example, .CS -\fBexpr 5 / 4\fR +\fBexpr\fR {5 / 4} .CE returns 1, while .CS -\fBexpr 5 / 4.0\fR -\fBexpr 5 / ( [string length "abcd"] + 0.0 )\fR +\fBexpr\fR {5 / 4.0} +\fBexpr\fR {5 / ( [string length "abcd"] + 0.0 )} .CE both return 1.25. -Floating-point values are always returned with a ``\fB.\fR'' -or an \fBe\fR so that they will not look like integer values. For -example, +Floating-point values are always returned with a +.QW \fB.\fR +or an +.QW \fBe\fR +so that they will not look like integer values. For example, .CS -\fBexpr 20.0/5.0\fR +\fBexpr\fR {20.0/5.0} .CE returns \fB4.0\fR, not \fB4\fR. - -.SH "STRING OPERATIONS" +.SS "STRING OPERATIONS" .PP String values may be used as operands of the comparison operators, although the expression evaluator tries to do comparisons as integer or floating-point when it can, -.VS 8.4 +i.e., when all arguments to the operator allow numeric interpretations, except in the case of the \fBeq\fR and \fBne\fR operators. -.VE 8.4 If one of the operands of a comparison is a string and the other -has a numeric value, the numeric operand is converted back to -a string using the C \fIsprintf\fR format specifier -\fB%d\fR for integers and \fB%g\fR for floating-point values. -For example, the commands +has a numeric value, a canonical string representation of the numeric +operand value is generated to compare with the string operand. +Canonical string representation for integer values is a decimal string +format. Canonical string representation for floating-point values +is that produced by the \fB%g\fR format specifier of Tcl's +\fBformat\fR command. For example, the commands .CS \fBexpr {"0x03" > "2"}\fR -\fBexpr {"0y" < "0x12"}\fR +\fBexpr {"0y" > "0x12"}\fR .CE both return 1. The first comparison is done using integer -comparison, and the second is done using string comparison after -the second operand is converted to the string \fB18\fR. +comparison, and the second is done using string comparison. Because of Tcl's tendency to treat values as numbers whenever -possible, it isn't generally a good idea to use operators like \fB==\fR +possible, it is not generally a good idea to use operators like \fB==\fR when you really want string comparison and the values of the -operands could be arbitrary; it's better in these cases to use -.VS 8.4 -the \fBeq\fR or \fBne\fR operators, or -.VE 8.4 -the \fBstring\fR command instead. - +operands could be arbitrary; it is better in these cases to use +the \fBeq\fR or \fBne\fR operators, or the \fBstring\fR command instead. .SH "PERFORMANCE CONSIDERATIONS" .PP Enclose expressions in braces for the best speed and the smallest @@ -385,7 +353,7 @@ then the \fBexpr\fR command will evaluate the expression \fB$a + 2*4\fR. Most expressions do not require a second round of substitutions. Either they are enclosed in braces or, if not, their variable and command substitutions yield numbers or strings -that don't themselves require substitutions. +that do not themselves require substitutions. However, because a few unbraced expressions need two rounds of substitutions, the bytecode compiler must emit @@ -394,9 +362,62 @@ The most expensive code is required for unbraced expressions that contain command substitutions. These expressions must be implemented by generating new code each time the expression is executed. - +.VS 8.5 +When the expression is unbraced to allow the substitution of a function or +operator, consider using the commands documented in the \fBmathfunc\fR(n) or +\fBmathop\fR(n) manual pages directly instead. +.VE 8.5 +.SH EXAMPLES +Define a procedure that computes an +.QW interesting +mathematical function: +.CS +proc tcl::mathfunc::calc {x y} { + \fBexpr\fR { ($x**2 - $y**2) / exp($x**2 + $y**2) } +} +.CE +.PP +Convert polar coordinates into cartesian coordinates: +.CS +# convert from ($radius,$angle) +set x [\fBexpr\fR { $radius * cos($angle) }] +set y [\fBexpr\fR { $radius * sin($angle) }] +.CE +.PP +Convert cartesian coordinates into polar coordinates: +.CS +# convert from ($x,$y) +set radius [\fBexpr\fR { hypot($y, $x) }] +set angle [\fBexpr\fR { atan2($y, $x) }] +.CE +.PP +Print a message describing the relationship of two string values to +each other: +.CS +puts "a and b are [\fBexpr\fR {$a eq $b ? {equal} : {different}}]" +.CE +.PP +Set a variable to whether an environment variable is both defined at +all and also set to a true boolean value: +.CS +set isTrue [\fBexpr\fR { + [info exists ::env(SOME_ENV_VAR)] && + [string is true -strict $::env(SOME_ENV_VAR)] +}] +.CE +.PP +Generate a random integer in the range 0..99 inclusive: +.CS +set randNum [\fBexpr\fR { int(100 * rand()) }] +.CE .SH "SEE ALSO" -array(n), string(n), Tcl(n) - +array(n), for(n), if(n), mathfunc(n), mathop(n), namespace(n), proc(n), +string(n), Tcl(n), while(n) .SH KEYWORDS arithmetic, boolean, compare, expression, fuzzy comparison +.SH COPYRIGHT +.nf +Copyright (c) 1993 The Regents of the University of California. +Copyright (c) 1994-2000 Sun Microsystems Incorporated. +Copyright (c) 2005 by Kevin B. Kenny <kennykb@acm.org>. All rights reserved. +.fi |
