summaryrefslogtreecommitdiffstats
path: root/doc/expr.n
diff options
context:
space:
mode:
Diffstat (limited to 'doc/expr.n')
-rw-r--r--doc/expr.n692
1 files changed, 348 insertions, 344 deletions
diff --git a/doc/expr.n b/doc/expr.n
index b43765c..cbb2395 100644
--- a/doc/expr.n
+++ b/doc/expr.n
@@ -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: