语法
该命令采用以下一般形式:
expr arg1 arg2 ...
运算符
下面列出了有效的运算符,按优先级降序分组:
- ~ ! : 一元减、一元加、按位非、逻辑非。这些操作数都不能应用于字符串操作数,按位非只能应用于整数。
- */% : 乘法、除法、余数。这些操作数都不能应用于字符串操作数,余数只能应用于整数。余数将始终具有与除数相同的符号和小于除数的绝对值。
- :加减。对任何数字操作数都有效。
- << >> :左右移动。仅对整数操作数有效。右移总是传播符号位。
- < > <= >= :布尔值小于、大于、小于或者等于和大于或者等于。如果条件为真,每个运算符产生 1,否则产生 0。这些运算符可以应用于字符串以及数字操作数,在这种情况下使用字符串比较。
- == != :布尔等于和不等于。每个运算符产生一个零/一个结果。对所有操作数类型都有效。
- & :按位与。仅对整数操作数有效。
- ^ : 按位异或者。仅对整数操作数有效。
- | : 按位或者。仅对整数操作数有效。
- && :逻辑与。如果两个操作数都非零,则产生 1 结果,否则产生 0。仅对布尔和数字(整数或者浮点)操作数有效。
- ||:逻辑或者。如果两个操作数都为零,则产生 0 结果,否则产生 1. 仅对布尔和数字(整数或者浮点)操作数有效。
- x?y:z : 类似在 C 中的If-then-else。如果 x 评估为非零,则结果是 y 的值。否则,结果是 z 的值。 x 操作数必须具有数值。
字符串操作
字符串值可以用作比较运算符的操作数,尽管表达式计算器会尽可能以整数或者浮点数进行比较。
如果比较的操作数之一是字符串而另一个操作数具有数值,则使用 C sprintf 格式说明符 %d(整数)和 %g(浮点值)将数字操作数转换回字符串。
例如,命令:
expr {"0x03" > "2"} expr {"0y" < "0x12"}
两者都返回 1.
第一次比较是使用整数比较完成的,第二次是在第二个操作数转换为字符串 18 之后使用字符串比较完成的。
由于 Tcl 倾向于尽可能将值视为数字,因此当我们确实需要字符串比较并且操作数的值可能是任意的时,使用 == 之类的运算符通常不是一个好主意;在这些情况下最好使用 string 命令。
类型、溢出和精度
所有涉及整数的内部计算都用 C 类型 long 完成,所有涉及浮点的内部计算都用 C 类型 double 完成。
将字符串转换为浮点数时,检测到指数溢出并导致 Tcl 错误。
对于从字符串到整数的转换,溢出的检测依赖于本地C库中的一些例程的行为,因此应该被认为是不可靠的。
在任何情况下,对于中间结果,通常无法可靠地检测整数上溢和下溢。
浮点上溢和下溢检测到硬件支持的程度,这通常非常可靠。
整数、浮点和字符串操作数的内部表示之间的转换根据需要自动完成。
对于算术计算,使用整数直到引入一些浮点数,然后使用浮点数。
例如,
expr 5 / 4
返回 1,而
expr 5 / 4.0 expr 5 / ( [string length "abcd"] + 0.0 )
两者都返回 1.25.
浮点值总是返回'.'点号或者e。
例如,
expr 20.0/5.0
返回 4.0 ,而不是 4 。
操作数
Tcl 表达式由操作数、运算符和括号的组合组成。
操作数和操作符和括号之间可以使用空格;它被表达式的指令忽略。
在可能的情况下,操作数被解释为整数值。
整数值可以用十进制(正常情况)、八进制(如果操作数的第一个字符是 0 )或者十六进制(如果操作数的前两个字符是 0x )指定。
如果操作数不具有上面给出的整数格式之一,则在可能的情况下将其视为浮点数。
可以以符合 ANSI 标准的 C 编译器接受的任何方式指定浮点数(除了在大多数安装中不允许使用 f 、 F 、 l 和 L 后缀)。
例如,以下所有都是有效的浮点数:2.1、3.、6e4、7.91e+16.
如果不可能进行数字解释,则操作数将作为字符串保留,并且只能对其应用有限的一组运算符。
可以通过以下任何一种方式指定操作数:
- 作为数值,整数或者浮点数。
- 作为 Tcl 变量,使用标准的 $ 符号。变量的值将用作操作数。
- 作为用双引号括起来的字符串。表达式解析器将对引号之间的信息执行反斜杠、变量和命令替换,并将结果值用作操作数。
- 作为用大括号括起来的字符串。左大括号和匹配的右大括号之间的字符将用作操作数而无需任何替换。
- 作为括号中的 Tcl 命令。该命令将被执行,其结果将用作操作数。
- 作为一个数学函数,其参数具有上述任何操作数形式,例如 sin($x) 。
示例,假设变量 a 的值为 3,变量 b 的值为 6.
expr 3.1 + $a6.1 expr 2 + "$a.$b"5.6 expr 4*[llength "6 2"]8 expr {{word one} < "word $a"}0
在shell中使用 expr命令计算数学表达式
Linux shell 的 expr 实用程序连接参数,然后将结果计算为 Tcl 表达式,将值返回到标准输出。
Tcl 表达式中允许的运算符是 C 表达式中允许的运算符的子集,它们与相应的 C 运算符具有相同的含义和优先级。
表达式几乎总是产生数字结果(整数或者浮点值)。
数学函数
Tcl 在表达式中支持以下数学函数:
- abs( arg) :返回 arg 的绝对值。 Arg 可以是整数或者浮点数,结果以相同的形式返回。
- acos( arg) :返回 arg 的反余弦值,范围为 [0,pi] 弧度。 Arg 应在 [-1,1] 范围内。
- asin( arg) :返回 arg 的反正弦,范围为 [-pi/2,pi/2] 弧度。 Arg 应在 [-1,1] 范围内。
- atan( arg) :返回 arg 的反正切,范围为 [-pi/2,pi/2] 弧度。
- atan2( x, y) :返回 y/x 的反正切,范围为 [-pi,pi] 弧度。 x 和 y 不能都为 0。
- ceil(arg):返回不小于arg的最小整数值。
- cos( arg) :返回 arg 的余弦值,以弧度为单位。
- cosh( arg) :返回 arg 的双曲余弦值。如果结果会导致溢出,则返回错误。
- double( arg) :如果 arg 是浮点值,则返回 arg,否则将 arg 转换为浮点数并返回转换后的值。
- exp( arg) :返回 arg 的指数,定义为 e**arg。如果结果会导致溢出,则返回错误。
- floor( arg) :返回不大于 arg 的最大整数值。
- fmod( x, y) :返回 x 除以 y 的浮点余数。如果 y 为 0,则返回错误。
- hypot( x, y) :计算直角三角形 (xx+yy) 的斜边长度。
- int( arg) : 如果 arg 是整数值,则返回 arg,否则通过截断将 arg 转换为整数并返回转换后的值。
- log( arg) :返回 arg 的自然对数。 Arg 必须是正值。
- log10( arg) :返回 arg 的以 10 为底的对数。 Arg 必须是正值。
- pow( x, y) :计算 x 的 y 次幂值。如果 x 为负,则 y 必须是整数值。
- rand() :返回一个从零到刚好小于一的浮点数,或者用数学术语来说,范围是 [0,1)。种子来自机器的内部时钟,也可以使用 srand 功能手动设置。
- round( arg) : 如果 arg 是整数值,则返回 arg,否则通过四舍五入将 arg 转换为整数并返回转换后的值。
- sin( arg) :返回 arg 的正弦值,以弧度为单位。
- sinh( arg) :返回 arg 的双曲正弦值。如果结果会导致溢出,则返回错误。
- sqrt( arg) :返回 arg 的平方根。 Arg 必须为非负值。
- srand( arg) :arg 必须是整数,用于重置随机数生成器的种子。返回该种子的第一个随机数。每个解释器都有自己的种子。
- tan( arg) :返回 arg 的正切值,以弧度为单位。
- tanh( arg) :返回 arg 的双曲正切值。
除了这些预定义函数,应用程序还可以使用 Tcl_CreateMathFunc() 定义添加函数。