Linux / Unix命令:expr

名称

expr - 评估一个表达式

概要

expr arg ? arg arg ... ?

连接arg (在它们之间添加分隔符空格),将结果评估为Tcl表达式,并返回该值。 Tcl表达式中允许的运算符是C表达式中允许的运算符的子集,它们与相应的C运算符具有相同的含义和优先级。 表达式几乎总是产生数值结果 (整数或浮点值)。 例如,表达式

表达8.2 + 6

评估为14.2。 Tcl表达式与C表达式在指定操作数的方式上不同。 另外,Tcl表达式支持非数字操作数和字符串比较。

操作数

Tcl表达式由操作数,运算符和括号组成。 操作数和运算符与括号之间可以使用空格; 它被表达式的指示忽略。 在可能的情况下,操作数被解释为整数值。 整数值可以用十进制(正常情况下),八进制(如果操作数的第一个字符为0 )或十六进制(如果操作数的前两个字符为0x )指定。 如果一个操作数没有上面给出的整数格式之一,那么它将被视为一个浮点数,如果这是可能的话。 浮点数可以用符合ANSI的C编译器接受的任何方式指定(除了在大多数安装中不允许使用f , F , l和L后缀)。 例如,以下所有内容都是有效的浮点数:2.1,3.,6e4,7.91e + 16。 如果没有数字解释是可能的,那么操作数被保留为一个字符串(并且只有有限的一组操作符可以应用于它)。

操作数可以通过以下任何方式指定:

[1]

作为数值,可以是整数或浮点数。

[2]

作为一个Tcl变量,使用标准的$表示法。 该变量的值将被用作操作数。

[3]

作为用双引号括起来的字符串。 表达式解析器将对引号之间的信息执行反斜杠,变量和命令替换,并将结果值用作操作数

[4]

作为括号中的字符串。 开放大括号和匹配大括号之间的字符将被用作操作数,而不进行任何替换。

[5]

作为括号中的Tcl命令。 该命令将被执行并且其结果将被用作操作数。

[6]

作为一个数学函数,其参数具有任何上述形式的操作数,如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

运营商

下面列出了有效的运算符,按照优先级的降序进行分组:

- +〜!

一元减号,一元加号,按位不是,逻辑非。 这些操作数中没有一个可以应用于字符串操作数,而按位NOT可以仅应用于整数。

* /%

相乘,除,余数。 这些操作数中没有一个可以应用于字符串操作数,余数可能仅适用于整数。 其余的将始终具有与除数相同的符号和小于除数的绝对值。

+ -

加减法。 适用于任何数字操作数。

<< >>

左右移动。 仅对整数操作数有效。 右移总是传播符号位。

<> <=> =

布尔减少,大于,小于或等于,大于或等于。 如果条件为真,则每个运算符产生1,否则为0。 这些运算符可以应用于字符串以及数字操作数,在这种情况下使用字符串比较。

==!=

布尔相等而不相等。 每个运算符产生一个零/一个结果。 适用于所有操作数类型。

&

按位与。 仅对整数操作数有效。

^

按位独占OR。 仅对整数操作数有效。

|

按位或。 仅对整数操作数有效。

&&

逻辑AND。 如果两个操作数都为非零,则产生1结果,否则为0。 仅对布尔型和数字(整数或浮点型)操作数有效。

||

逻辑或。 如果两个操作数均为零,则产生0结果,否则为1。 仅对布尔型和数字(整数或浮点型)操作数有效。

x ? y : z

If-then-else,如在C.如果x评估为非零,那么结果是y的值。 否则,结果就是z的值。 x操作数必须有一个数值。

有关每个操作员生成的结果的更多详细信息,请参阅C手册。 所有的二元运算符在相同的优先级内从左到右分组。 例如,该命令

expr 4 * 2 <7

返回0。

&& , || ,和?:运算符具有“懒惰评估”,就像在C中一样,这意味着如果不需要确定结果,操作数就不会被评估。 例如,在命令中

expr {$ v? [a]:[b]}

根据$ v的值,实际上只会评估[a]或[b]中的 一个 。 但是请注意,只有整个表达式用大括号括起来才是正确的。 否则,在调用expr命令之前,Tcl解析器将同时评估[a]和[b] 。

数学函数

Tcl在表达式中支持以下数学函数:

abs cosh log sqrt acos double log10 srand asin exp pow tan atan floor rand tanh atan2 fmod round ceil hypot sin cos int sinh

abs( arg )

返回arg的绝对值。 Arg可以是整数或浮点数,结果以相同的形式返回。

acos( arg )

返回arg的反余弦,范围为[0,pi]弧度。 Arg应该在[-1,1]的范围内。

asin( arg )

返回arg的反正弦值,范围为[-pi / 2,pi / 2]弧度。 Arg应该在[-1,1]的范围内。

阿坦( 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的双曲余弦。 如果结果会导致溢出,则返回错误。

双( arg )

如果arg是一个浮点值,则返回arg ,否则将arg转换为浮点并返回转换后的值。

exp( arg )

返回arg的指数,定义为e ** arg 。 如果结果会导致溢出,则返回错误。

地板( arg )

返回不大于arg的最大整数值。

fmod( x,y )

返回x除以y的浮点余数。 如果y为0,则返回错误。

hypot( x,y )

计算直角三角形( x * x + y * y )斜边的长度。

int( arg )

如果arg是整数值,则返回arg ,否则通过截断将arg转换为整数并返回转换后的值。

日志( arg )

返回arg的自然对数。 Arg必须是正值。

log10( arg )

返回arg的 10进制的对数。 Arg必须是正值。

pow( x,y )

计算x增加到y的值 。 如果x是负数,则y必须是整数值。

RAND()

返回从零到小于1的浮点数,或者在数学术语中,返回范围[0,1)。 种子来自机器的内部时钟,或者可以通过srand功能进行手动设置。

圆( arg )

如果arg是整数值,则返回arg ,否则通过舍入将arg转换为整数并返回转换后的值。

罪( arg )

返回arg的正弦值,以弧度为单位。

sinh( arg )

返回arg的双曲正弦值。 如果结果会导致溢出,则返回错误。

sqrt( arg )

返回arg的平方根。 Arg必须是非负的。

srand( arg )

arg必须是一个整数,用于重置随机数生成器的种子。 返回该种子的第一个随机数。 每个口译员都有自己的种子。

tan( arg )

返回arg的正切值,以弧度为单位。

tanh( arg )

返回arg的双曲正切。

除了这些预定义的函数之外,应用程序还可以使用Tcl_CreateMathFunc ()定义附加函数。

类型,溢出和精度

所有涉及整数的内部计算都是用C型long来完成的,所有涉及浮点的内部计算都是用C型double来完成的。 将字符串转换为浮点时,检测到指数溢出并导致Tcl错误。 对于从字符串转换为整数,溢出的检测取决于本地C库中一些例程的行为,因此应视为不可靠。 在任何情况下,对于中间结果,通常不会可靠地检测到整数溢出和下溢。 在硬件支持的程度上检测浮点溢出和下溢,通常非常可靠。

整数,浮点和字符串操作数的内部表示之间的转换根据需要自动完成。 对于算术计算,整数一直使用,直到引入一些浮点数,然后使用浮点数。 例如,

expr 5/4

返回1,while

expr 5 / 4.0 expr 5 /([字符串长度“abcd”] + 0.0)

两者都返回1.25。 浮点值总是以``返回。 ''或e,这样它们看起来不像整数值。 例如,

expr 20.0 / 5.0

返回4.0 ,而不是4 。

字符串操作

字符串值可以用作比较运算符的操作数,尽管表达式计算器可能会尝试将其作为整数或浮点进行比较。 如果比较操作数中的一个是字符串,另一个是数字值,则数字操作数将转换回使用C sprintf格式说明符%d作为整数, %g作为浮点值的字符串。 例如,命令

expr {“0x03”>“2”} expr {“0y”<“0x12”}

两者都返回1.第一个比较是使用整数比较完成的,第二个比较是在第二个操作数转换为字符串18后使用字符串比较完成的。 由于Tcl倾向于尽可能将值视为数字,因此,如果您真的想要字符串比较,并且操作数的值可以是任意的,那么使用像==这样的运算符通常不是一个好主意; 在这些情况下最好使用string命令。

性能考虑

将表达式括在大括号中以获得最佳速度和最小存储要求。 这允许Tcl字节码编译器生成最佳代码。

如上所述,表达式被替换两次:一次由Tcl解析器取代,一次由expr命令取代。 例如,命令

设置3 组b {$ a + 2} expr $ b * 4

返回11,不是4的倍数。这是因为Tcl解析器将首先用变量b代替$ a + 2 ,然后expr命令将计算表达式$ a + 2 * 4 。

大多数表达式不需要第二轮替换。 要么它们被括在大括号中,要么它们的变量和命令替换产生不需要替换的数字或字符串。 但是,由于少数无束缚的表达式需要两轮替换,所以字节码编译器必须发出额外的指令来处理这种情况。 包含命令替换的无支撑表达式需要最昂贵的代码。 每次执行表达式时都必须通过生成新代码来实现这些表达式。

关键词

算术, 布尔值 ,比较,表达式,模糊比较

重要提示:使用man命令( %man )查看特定计算机上的命令使用方式。