Linux / Unix命令:expr

名称

expr - 评估一个表达式

概要

expr argarg arg ...

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

表达8.2 + 6

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

操作数

Tcl表达式由操作数,运算符和括号组成。 操作数和运算符与括号之间可以使用空格; 它被表达式的指示忽略。 在可能的情况下,操作数被解释为整数值。 整数值可以用十进制(正常情况下),八进制(如果操作数的第一个字符为0 )或十六进制(如果操作数的前两个字符为0x )指定。 如果一个操作数没有上面给出的整数格式之一,那么它将被视为一个浮点数,如果这是可能的话。 浮点数可以用符合ANSI的C编译器接受的任何方式指定(除了在大多数安装中不允许使用fFlL后缀)。 例如,以下所有内容都是有效的浮点数: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]弧度。 xy不能都是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 )查看特定计算机上的命令使用方式。