More about Math Expressions

This section describes a few fine points about math in Tcl scripts. In Tcl 7.6 and earlier versions math is not that efficient because of conversions between strings and numbers. The expr command must convert its arguments from strings to numbers. It then does all its computations with double precision floating point values. The result is formatted into a string that has, by default, 12 significant digits. This number can be changed by setting the tcl_precision variable to the number of significant digits desired. Seventeen digits of precision are enough to ensure that no information is lost when converting back and forth between a string and an IEEE double precision number:

Example 1-18 Controlling precision with tcl_precision.
expr 1 / 3
=> 0
expr 1 / 3.0
=> 0.333333333333
set tcl_precision 17
=> 17
expr 1 / 3.0
# The trailing 1 is the IEEE rounding digit
=> 0.33333333333333331
					

In Tcl 8.0 and later versions, the overhead of conversions is eliminated in most cases by the built-in compiler. Even so, Tcl was not designed to support math-intensive applications. You may want to implement math-intensive code in a compiled language and register the function as a Tcl command as described in Chapter 44.

There is support for string comparisons by expr, so you can test string values in if statements. You must use quotes so that expr knows to do string comparisons:

if {$answer == "yes"} {... }

However, the string compare and string equal commands described in Chapter 4 are more reliable because expr may do conversions on strings that look like numbers. The issues with string operations and expr are discussed on page 48.

Expressions can include variable and command substitutions and still be grouped with curly braces. This is because an argument to expr is subject to two rounds of substitution: one by the Tcl interpreter, and a second by expr itself. Ordinarily this is not a problem because math values do not contain the characters that are special to the Tcl interpreter. The second round of substitutions is needed to support commands like while and if that use the expression evaluator internally.

Grouping expressions can make them run more efficiently.



You should always group expressions in curly braces and let expr do command and variable substitutions. Otherwise, your values may suffer extra conversions from numbers to strings and back to numbers. Not only is this process slow, but the conversions can loose precision in certain circumstances. For example, suppose x is computed from a math function:

set x [expr {sqrt(2.0)}]

At this point the value of x is a double-precision floating point value, just as you would expect. If you do this:

set two [expr $x * $x]

then you may or may not get 2.0 as the result! This is because Tcl will substitute $x and expr will concatenate all its arguments into one string, and then parse the expression again. In contrast, if you do this:

set two [expr {$x * $x}]

then expr will do the substitutions, and it will be careful to preserve the floating point value of x. The expression will be more accurate and run more efficiently because no string conversions will be done. The story behind Tcl values is described in more detail in Chapter 44 on C programming and Tcl.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.137.170.14