diff options
Diffstat (limited to 'doc/expr.n')
| -rw-r--r-- | doc/expr.n | 692 | 
1 files changed, 348 insertions, 344 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.10.2.1 2003/07/04 22:25:23 dkf 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,413 +15,418 @@ 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), -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. -Expressions almost always yield numeric results -(integer or floating-point values). +Concatenates \fIarg\fRs, separated by a space, into an expression, and evaluates +that expression, returning its value. +The operators permitted in an expression 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. +The value of an expression is often a numeric result, either an integer or a +floating-point value, but may also be a non-numeric value.  For example, the expression +.PP  .CS -\fBexpr 8.2 + 6\fR +\fBexpr\fR 8.2 + 6  .CE +.PP  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 -.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). -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 -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). -.PP -.VS 8.4 -On 32-bit systems, integer values MAX_INT (0x7FFFFFFF) and MIN_INT -(-0x80000000) will be represented as 32-bit values, and integer values -outside that range will be represented as 64-bit values (if that is -possible at all.) -.VE 8.4 -.PP -Operands may be specified in any of the following ways: +Expressions differ from C expressions in the way that +operands are specified.  Expressions also support +non-numeric operands, string comparisons, and some +additional operators not found in C. +.PP +When an expression evaluates to an integer, the value is the decimal form of +the integer, and when an expression evaluates to a floating-point number, the +value is the form produced by the \fB%g\fR format specifier of Tcl's +\fBformat\fR command. +.SS OPERANDS +.PP +An expression consists of a combination of operands, operators, parentheses and +commas, possibly with whitespace between any of these elements, which is +ignored. +An integer operand may be specified in decimal, binary +(the first two characters are \fB0b\fR), octal +(the first two characters are \fB0o\fR), or hexadecimal +(the first two characters are \fB0x\fR) form.  For +compatibility with older Tcl releases, an operand that begins with \fB0\fR is +interpreted as an octal integer even if the second character is not \fBo\fR. +A floating-point number may be specified in any of several +common decimal formats, and may use the decimal point \fB.\fR, +\fBe\fR or \fBE\fR for scientific notation, and +the sign characters \fB+\fR and \fB\-\fR.  The +following are all valid floating-point numbers:  2.1, 3., 6e4, 7.91e+16. +The strings \fBInf\fR +and \fBNaN\fR, in any combination of case, are also recognized as floating point +values.  An operand that doesn't have a numeric interpretation must be quoted +with either braces or with double quotes. +.PP +An operand 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 Tcl variable, using standard \fB$\fR notation. -The variable's value will be used as the operand. +As a boolean value, using any form understood by \fBstring is\fR +\fBboolean\fR.  .IP [3] -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 +As a variable, using standard \fB$\fR notation. +The value of the variable is then the value of the operand.  .IP [4] -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. +As a string enclosed in double-quotes. +Backslash, variable, and command substitution are performed as described in +\fBTcl\fR.  .IP [5] -As a Tcl command enclosed in brackets. -The command will be executed and its result will be used as -the operand. +As a string enclosed in braces. +The operand is treated as a braced value as described in \fBTcl\fR.  .IP [6] -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. -.LP -Where substitutions occur above (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. -As discussed below, it is usually best to enclose expressions -in braces to prevent the command parser from performing substitutions -on the contents. -.PP -For some examples of simple expressions, suppose the variable -\fBa\fR has the value 3 and -the variable \fBb\fR has the value 6. -Then the command on the left side of each of the lines below -will produce the value on the right side of the line: +As a Tcl command enclosed in brackets. +Command substitution is performed as described in \fBTcl\fR. +.IP [7] +As a mathematical function such as \fBsin($x)\fR, whose arguments have any of the above +forms for operands.  See \fBMATH FUNCTIONS\fR below for +a discussion of how mathematical functions are handled. +.PP +Because \fBexpr\fR parses and performs substitutions on values that have +already been parsed and substituted by \fBTcl\fR, it is usually best to enclose +expressions in braces to avoid the first round of substitutions by +\fBTcl\fR. +.PP +Below are some examples of simple expressions where the value of \fBa\fR is 3 +and the value of \fBb\fR is 6.  The command on the left side of each line +produces the value on the right side. +.PP  .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: +For operators having both a numeric mode and a string mode, the numeric mode is +chosen when all operands have a numeric interpretation.  The integer +interpretation of an operand is preferred over the floating-point +interpretation.  To ensure string operations on arbitrary values it is generally a +good idea to use \fBeq\fR, \fBne\fR, or the \fBstring\fR command instead of +more versatile operators such as \fB==\fR. +.PP +Unless otherwise specified, operators accept non-numeric operands.  The value +of a boolean operation is 1 if true, 0 otherwise.  See also \fBstring is\fR +\fBboolean\fR.  The valid operators, most of which are also available as +commands in the \fBtcl::mathop\fR namespace (see \fBmathop\fR(n)), 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 -may be applied to string operands, and bit-wise NOT may be -applied only to integers. +. +Unary minus, unary plus, bit-wise NOT, logical NOT.  These operators +may only be applied to numeric operands, and bit-wise NOT may only be +applied to integers. +.TP 20 +\fB**\fR +. +Exponentiation.  Valid for numeric operands.  .TP 20  \fB*\0\0/\0\0%\fR -Multiply, divide, remainder.  None of these operands 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. +. +Multiply and divide, which are valid for numeric operands, and remainder, which +is valid for integers.  The remainder, an absolute value smaller than the +absolute value of the divisor, has the same sign as the divisor. +.RS +.PP +When applied to integers, division and remainder can be +considered to partition the number line into a sequence of +adjacent non-overlapping pieces, where each piece is the size of the divisor; +the quotient identifies which piece the dividend lies within, and the +remainder identifies where within that piece the dividend lies. 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. +. +Add and subtract.  Valid for numeric operands.  .TP 20  \fB<<\0\0>>\fR -Left and right shift.  Valid for integer operands only. +. +Left and right shift.  Valid for integers.  A right shift always propagates the sign bit.  .TP 20  \fB<\0\0>\0\0<=\0\0>=\fR -Boolean less, greater, less than or equal, and greater than or equal. -Each operator produces 1 if the condition is true, 0 otherwise. -These operators may be applied to strings as well as numeric operands, -in which case string comparison is used. +. +Boolean less than, greater than, less than or equal, and greater than or equal.  .TP 20  \fB==\0\0!=\fR -Boolean equal and not equal.  Each operator produces a zero/one result. -Valid for all operand types. -.VS 8.4 +. +Boolean equal and not equal.  .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 +. +Boolean string equal and string not equal. +.TP 20 +\fBin\0\0ni\fR +. +List containment and negated list containment.  The first argument is +interpreted as a string, the second as a list.  \fBin\fR tests for membership +in the list, and \fBni\fR is the inverse.  .TP 20  \fB&\fR -Bit-wise AND.  Valid for integer operands only. +. +Bit-wise AND.  Valid for integer operands.  .TP 20  \fB^\fR -Bit-wise exclusive OR.  Valid for integer operands only. +. +Bit-wise exclusive OR.  Valid for integer operands.  .TP 20  \fB|\fR -Bit-wise OR.  Valid for integer operands only. +. +Bit-wise OR.  Valid for integer operands.  .TP 20  \fB&&\fR -Logical AND.  Produces a 1 result if both operands are non-zero, -0 otherwise. -Valid for boolean and numeric (integers or floating-point) operands only. +. +Logical AND.  If both operands are true, the result is 1, or 0 otherwise. +  .TP 20  \fB||\fR -Logical OR.  Produces a 0 result if both operands are zero, 1 otherwise. -Valid for boolean and numeric (integers or floating-point) operands only. +. +Logical OR.  If both operands are false, the result is 0, or 1 otherwise.  .TP 20  \fIx\fB?\fIy\fB:\fIz\fR -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. -.LP -See the C manual for more details on the results -produced by each operator. -All of the binary operators group left-to-right within the same -precedence level.  For example, the command +. +If-then-else, as in C.  If \fIx\fR is false , the result is the value of +\fIy\fR.  Otherwise the result is the value of \fIz\fR. +.PP +The exponentiation operator promotes types in the same way that the multiply +and divide operators do, and the result is is the same as the result of +\fBpow\fR. +Exponentiation groups right-to-left within a precedence level. Other binary +operators group left-to-right.  For example, the value of +.PP  .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,  +is 0, while the value of +.PP +.CS +\fBexpr\fR {2**3**2} +.CE +.PP +is 512. +.PP +As in C, \fB&&\fR, \fB||\fR, and \fB?:\fR feature +.QW "lazy evaluation" ,  which means that operands are not evaluated if they are -not needed to determine the outcome.  For example, in the command +not needed to determine the outcome.  For example, in +.PP +.CS +\fBexpr\fR {$v ? [a] : [b]} +.CE +.PP +only one of \fB[a]\fR or \fB[b]\fR is evaluated, +depending on the value of \fB$v\fR.  This is not true of the normal Tcl parser, +so it is normally recommended to enclose the arguments to \fBexpr\fR in braces. +Without braces, as in +\fBexpr\fR $v ? [a] : [b] +both \fB[a]\fR and \fB[b]\fR are evaluated before \fBexpr\fR is even called. +.PP +For more details on the results +produced by each operator, see the documentation for C. +.SS "MATH FUNCTIONS" +.PP +A mathematical function such as \fBsin($x)\fR is replaced with a call to an ordinary +Tcl command in the \fBtcl::mathfunc\fR namespace.  The evaluation +of an expression such as +.PP +.CS +\fBexpr\fR {sin($x+$y)} +.CE +.PP +is the same in every way as the evaluation of +.PP +.CS +\fBexpr\fR {[tcl::mathfunc::sin [\fBexpr\fR {$x+$y}]]} +.CE +.PP +which in turn is the same as the evaluation of +.PP  .CS -\fBexpr {$v ? [a] : [b]}\fR +tcl::mathfunc::sin [\fBexpr\fR {$x+$y}]  .CE -only one of \fB[a]\fR or \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" -.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	\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	\fBwide\fR -\fBceil\fR	\fBhypot\fR	\fBsin\fR -\fBcos\fR	\fBint\fR	\fBsinh\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 -\fBacos(\fIarg\fB)\fR -Returns the arc cosine of \fIarg\fR, in the range [\fI0\fR,\fIpi\fR] -radians. \fIArg\fR should be in the range [\fI-1\fR,\fI1\fR]. -.TP -\fBasin(\fIarg\fB)\fR -Returns the arc sine of \fIarg\fR, in the range [\fI-pi/2\fR,\fIpi/2\fR] -radians.  \fIArg\fR should be in the range [\fI-1\fR,\fI1\fR]. -.TP -\fBatan(\fIarg\fB)\fR -Returns the arc tangent of \fIarg\fR, in the range [\fI-pi/2\fR,\fIpi/2\fR] -radians. -.TP -\fBatan2(\fIy, x\fB)\fR -Returns the arc tangent of \fIy\fR/\fIx\fR, in the range [\fI-pi\fR,\fIpi\fR] -radians.  \fIx\fR and \fIy\fR cannot both be 0.  If \fIx\fR is greater -than \fI0\fR, this is equivalent to \fBatan(\fIy/x\fB)\fR. -.TP -\fBceil(\fIarg\fB)\fR -Returns the smallest integral floating-point value (i.e. with a zero -fractional part) 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-point value, returns \fIarg\fR, otherwise converts -\fIarg\fR to floating-point and returns the converted value. -.TP -\fBexp(\fIarg\fB)\fR -Returns the exponential of \fIarg\fR, defined as \fIe\fR**\fIarg\fR. -If the result would cause an overflow, an error is returned. -.TP -\fBfloor(\fIarg\fB)\fR -Returns the largest integral floating-point value (i.e. with a zero -fractional part) 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 -\fBsqrt(\fIx\fR*\fIx\fR+\fIy\fR*\fIy\fB)\fR. -.TP -\fBint(\fIarg\fB)\fR -.VS 8.4 -If \fIarg\fR is an integer value of the same width as the machine -word, returns \fIarg\fR, otherwise -converts \fIarg\fR to an integer (of the same size as a machine word, -i.e. 32-bits on 32-bit systems, and 64-bits on 64-bit systems) by -truncation and returns the converted value. -.VE 8.4 -.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 pseudo-random floating-point value in the range (\fI0\fR,\fI1\fR).   -The generator algorithm is a simple linear congruential generator that -is not cryptographically secure.  Each result from \fBrand\fR completely -determines all future results from subsequent calls to \fBrand\fR, so -\fBrand\fR should not be used to generate a sequence of secrets, such as -one-time passwords.  The seed of the generator is initialized from the -internal clock of the machine or may be set with the \fBsrand\fR 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 of \fBrand\fR.  Returns the first random -number (see \fBrand()\fR) from that seed.  Each interpreter has its 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. -.TP -\fBwide(\fIarg\fB)\fR -.VS 8.4 -Converts \fIarg\fR to an integer value at least 64-bits wide (by sign-extension -if \fIarg\fR is a 32-bit number) if it is not one already. -.VE 8.4 -.PP -In addition to these predefined functions, applications may -define additional functions using \fBTcl_CreateMathFunc\fR(). -.SH "TYPES, OVERFLOW, AND PRECISION" -.PP -All internal computations involving integers are done with the C type -\fIlong\fR, and 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 +.PP +\fBtcl::mathfunc::sin\fR is resolved as described in +\fBNAMESPACE RESOLUTION\fR in the \fBnamespace\fR(n) documentation.   Given the +default value of \fBnamespace path\fR, \fB[namespace +current]::tcl::mathfunc::sin\fR or \fB::tcl::mathfunc::sin\fR are the typical +resolutions. +.PP +As in C, a mathematical function may accept multiple arguments separated by commas. Thus, +.PP +.CS +\fBexpr\fR {hypot($x,$y)} +.CE +.PP +becomes +.PP +.CS +tcl::mathfunc::hypot $x $y +.CE +.PP +See the \fBmathfunc\fR(n) documentation for the math functions that are +available by default. +.SS "TYPES, OVERFLOW, AND PRECISION" +.PP +When needed to guarantee exact performance, internal computations involving +integers use the LibTomMath multiple precision integer library.  In Tcl releases +prior to 8.5, integer calculations were performed using 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 should instead call +\fBint()\fR or \fBwide()\fR, which do truncate. +.PP +Internal floating-point computations are +performed using the \fIdouble\fR C type. +When converting a string to floating-point value, exponent overflow is +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. +fairly reliable. +.PP +Conversion among internal representations for integer, floating-point, and +string operands is done automatically as needed.  For arithmetic computations, +integers are used until some floating-point number is introduced, after which +floating-point values are used.  For example,  .PP -Conversion among internal representations for integer, floating-point, -and string operands is done automatically as needed. -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 +.PP  returns 1, while +.PP  .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 +.PP  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, +A floating-point result can be distinguished from an integer result by the +presence of either +.QW \fB.\fR +or +.QW \fBe\fR +.PP +. For example, +.PP  .CS -\fBexpr 20.0/5.0\fR +\fBexpr\fR {20.0/5.0}  .CE +.PP  returns \fB4.0\fR, not \fB4\fR. - -.SH "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 -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 +.SH "PERFORMANCE CONSIDERATIONS" +.PP +Where an expression contains syntax that Tcl would otherwise perform +substitutions on, enclosing an expression in braces or otherwise quoting it +so that it's a static value allows the Tcl compiler to generate bytecode for +the expression, resulting in better speed and smaller storage requirements. +This also avoids issues that can arise if Tcl is allowed to perform +substitution on the value before \fBexpr\fR is called. +.PP +In the following example, the value of the expression is 11 because the Tcl parser first +substitutes \fB$b\fR and \fBexpr\fR then substitutes \fB$a\fR.  Enclosing the +expression in braces would result in a syntax error.  .CS -\fBexpr {"0x03" > "2"}\fR -\fBexpr {"0y" < "0x12"}\fR +set a 3 +set b {$a + 2} +\fBexpr\fR $b*4  .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. -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 -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. +.PP -.SH "PERFORMANCE CONSIDERATIONS" +When an expression is generated at runtime, like the one above is, the bytcode +compiler must ensure that new code is generated each time the expression +is evaluated.  This is the most costly kind of expression from a performance +perspective.  In such cases, consider directly using the commands described in +the \fBmathfunc\fR(n) or \fBmathop\fR(n) documentation instead of \fBexpr\fR. + +Most expressions are not formed at runtime, but are literal strings or contain +substitutions that don't introduce other substitutions.  To allow the bytecode +compiler to work with an expression as a string literal at compilation time, +ensure that it contains no substitutions or that it is enclosed in braces or +otherwise quoted to prevent Tcl from performing substitutions, allowing +\fBexpr\fR to perform them instead. +.SH EXAMPLES  .PP -Enclose expressions in braces for the best speed and the smallest -storage requirements. -This allows the Tcl bytecode compiler to generate the best code. +A numeric comparison whose result is 1: +.CS +\fBexpr\fR {"0x03" > "2"} +.CE  .PP -As mentioned above, expressions are substituted twice: -once by the Tcl parser and once by the \fBexpr\fR command. -For example, the commands +A string comparison whose result is 1:  .CS -\fBset a 3\fR -\fBset b {$a + 2}\fR -\fBexpr $b*4\fR +\fBexpr\fR {"0y" > "0x12"} +.CE +.PP +Define a procedure that computes an +.QW interesting +mathematical function: +.PP +.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: +.PP +.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: +.PP +.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: +.PP +.CS +puts "a and b are [\fBexpr\fR {$a eq $b ? {equal} : {different}}]" +.CE +.PP +Set a variable indicating whether an environment variable is defined and has +value of true: +.PP +.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: +.PP +.CS +set randNum [\fBexpr\fR { int(100 * rand()) }]  .CE -return 11, not a multiple of 4. -This is because the Tcl parser will first substitute \fB$a + 2\fR for -the variable \fBb\fR, -then the \fBexpr\fR command will evaluate the expression \fB$a + 2*4\fR. -.PP -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. -However, because a few unbraced expressions  -need two rounds of substitutions, -the bytecode compiler must emit -additional instructions to handle this situation. -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. -  .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 +'\" Local Variables: +'\" mode: nroff +'\" End: | 
