Tuesday, June 12, 2012

TCL - Results of a command - Math 101


The Tcl command for doing math type operations is expr. The following discussion of the expr command is extracted and adapted from the expr man page. Many commands use expr behind the scenes in order to evaluate test expressions, such as ifwhile and for loops, discussed in later sections. All of the advice given here for expr also holds for these other commands.
expr takes all of its arguments ("2 + 2" for example) and evaluates the result as a Tcl "expression" (rather than a normal command), and returns the value. The operators permitted in Tcl expressions include all the standard math functions, logical operators, bitwise operators, as well as math functions like rand()sqrt()cosh() and so on. Expressions almost always yield numeric results (integer or floating-point values).
Performance tip: enclosing the arguments to expr in curly braces will result in faster code. So do expr {$i * 10}instead of simply expr $i * 10
WARNING: You should always use braces when evaluating expressions that may contain user input, to avoid possible security breaches. The expr command performs its own round of substitutions on variables and commands, so you should use braces to prevent the Tcl interpreter doing this as well (leading to double substitution). To illustrate the danger, consider this interactive session:
% set userinput {[puts DANGER!]}
[puts DANGER!]
ut == 1 DANGER! 0 % ex
% expr $userin ppr {$userinput == 1}
0
In the first example, the code contained in the user-supplied input is evaluated, whereas in the second the braces prevent this potential danger. As a general rule, always surround expressions with braces, whether usingexpr directly or some other command that takes an expression (such as if or while).

OPERANDS

A Tcl expression consists of a combination of operands, operators, and parentheses. White space may be used between operands, operators and parentheses; it is ignored by the expression processor. 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 0), or in hexadecimal (if the first two characters of the operand are 0x).
Note that the octal and hexadecimal conversion takes place differently in the expr command than in the Tcl substitution phase. In the substitution phase, a \x32 would be converted to an ascii "2", while expr would convert0x32 to a decimal 50.
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. For example, all of the following are valid floating-point numbers:
2.1
3.
7.
6E
491e+16
.000001
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).
Note however, that it does not support numbers of the following forms:
2,1 - a decimal comma, instead of a decimal point
2,100 - a thousands separator
It is possible to deal with numbers in that form, but you will have to convert these "strings" to numbers in the standard form first.
Beware of leading zeros: 0700 is not interpreted as the decimal number 700 (seven hundred), but as the octalnumber 700 = 7*8*8 = 448 (decimal).
Worse, if the number contains a digit 8 or 9 an error results:
% expr {0900+1}
expected integer but got "0900" (looks like invalid octal number)
Octal numbers are in fact a relic of the past, when such number formats were much more common.
Operands may be specified in any of the following ways:
  • As an numeric value, either integer or floating-point.
  • As a Tcl variable, using standard $ notation. The variable's value will be used as the operand.

OPERATORS

The valid operators are listed below, grouped in decreasing order of precedence:
- + ~ !
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.
**
Exponentiation (works on both floating-point numbers and integers)
* / %
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.
+ -
Add and subtract. Valid for any numeric operands.
<< >>
Left and right (bit) shift. Valid for integer operands only.
< > <= >=
Relational operators: 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 numeric operands as well as strings, in which case string comparison is used.
eq ne in ni
compare two strings for equality (eq) or inequality (ne). and two operators for checking if a string is contained in a list (in) or not (ni). These operators all return 1 (true) or 0 (false). Using these operators ensures that the operands are regarded exclusively as strings (and lists), not as possible numbers:
% expr { "9" == "9.0"}
1
expr { "9" eq "9.0"} 0
%
&
Bit-wise AND. Valid for integer operands only.
^
Bit-wise exclusive OR. Valid for integer operands only.
|
Bit-wise OR. Valid for integer operands only.
&&
Logical AND. Produces a 1 result if both operands are non-zero, 0 otherwise. Valid for numeric operands only (integers or floating-point).
||
Logical OR. Produces a 0 result if both operands are zero, 1 otherwise. Valid for numeric operands only (integers or floating-point).
x?y:z
If-then-else. If x evaluates to non-zero, then the result is the value of y. Otherwise the result is the value of z. The x operand must have a numeric value.
% set x 1
% expr { $x>0? ($x+1) : ($x-1) }
2

MATH FUNCTIONS

Tcl supports the following mathematical functions in expressions:
abs acos asin atan
atan2 bool ceil cos
floor fmod hypot int
cosh double entier exp isqrt log log10 max
and tan tanh wide
min pow rand round sin sinh sqrt s
r
Besides these functions, you can also apply commands within an expression. For instance:
% set x 1
% set w "Abcdef"
% expr { [string length $w]-2*$x }
4

TYPE CONVERSIONS

Tcl supports the following functions to convert from one representation of a number to another:
double int wide entier
  • double() converts a number to a floating-point number.
  • int() converts a number to an ordinary integer number (by truncating the decimal part).
  • wide() converts a number to a so-called wide integer number (these numbers have a larger range).
  • entier() coerces a number to an integer of appropriate size to hold it without truncation. This might return the same as int() or wide() or an integer of arbitrary size (in Tcl 8.5 and above).
The next lesson explains the various types of numbers in more detail.

Example

set X 100
set Y 256
r {$Y + $X}] set Z_LAB
set Z [ex pEL "$Y plus $X is "
s "The square root
puts "$Z_LABEL $Z" pu t of $Y is [expr { sqrt($Y) }]\n"
es \"5 + -3 * 4\" is: [expr {-3 * 4 + 5}]" puts "Because of the parentheses
puts "Because of the precedence ru l \"(5 + -3) * 4\" is: [expr {(5 + -3) * 4}]" set A 3 set B 4
e trigonometric functions work with radians ... # set pi6
puts "The hypotenuse of a triangle: [expr {hypot($A,$B)}]" # # T h[expr {3.1415926/6.0}] puts "The sine and cosine of pi/6: [expr {sin($pi6)}] [expr {cos($pi6)}]" # # Working with arrays #
set a(1) 10 set a(2) 7 set a(3) 17 set b 2
puts "Sum: [expr {$a(1)+$a($b)}]"

No comments:

Post a Comment

Popular Posts