Chinaunix首页 | 论坛 | 博客
  • 博客访问: 26615
  • 博文数量: 19
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 187
  • 用 户 组: 普通用户
  • 注册时间: 2015-10-14 16:24
文章分类

全部博文(19)

文章存档

2015年(19)

我的朋友

分类: 系统运维

2015-11-09 22:52:45

分类:


expr----计算数学表达式

语法:
expr arg ?arg arg ...? 

描述:
串接参数(在参数之间添加分隔符),将这些参数进行数学计算出数值并返回.tcl 的数学表达式与c 的数学表达式
部分相同,表达式一般返回整形或者浮点型,例如:
expr 8.2+6结果为14.2. tcl 在操作数上和c 有些许不同. tcl 还支持分数字操作符合字符串比较

操作数:
tcl 表达式由操作数,操作符和括号组成.空格用在操作数,操作符和括号之间,计算时被表达式指令忽略;一般操
作数都被解析为整形数,整形数可以指定为十进制(一般情况),八进制(首字符为0),或者16进制(首字符为0x),如
果一个操作数没有符合上述给定的格式,则可以把其当做浮点型处理.浮点型数对任意的ANSI兼容的C编译器所识别
(除了f,F,和L形式).例如,有效的浮点型数字:2.1, 3., 6e4, 7.91e+16.如果不能按照上述解析成整形和浮点型,则
操作数被解析成字符串.
在32-bit系统,整形数值范围在MAX_INT(0x7FFFFFFF)到MIN_INT(-0x80000000),超出边界值的将用64-bit表示
操作数按如下方式指定:
1.整形或者浮点型数值
2.boolean值
3.tcl变量,以$表示引用
4.由""括起来的字符串
5.{}中的字符串
6.[]括起来的命令
7.数学公式函数,如sin($x)
如果存在字符串内的替换,则由表达式的指令执行.然而命令解析,建议将同一表达式的所有字符通过括号等加以界定
对于一些简单的表达式,如a取值为3,b取值为6,则命令按照自左到右的顺序进行解析(最后一列为结果):

expr 3.1 + $a    6.1
expr 2 + "$a.$b"    5.6
expr 4*[llength "6 2"]    8
expr {{word one} < "word $a"}    0

操作符:
有效的操作符如下:
- + ~ !:
一元运算符,分别表示:减(取负),加,按位非,逻辑非.这些运算符不能用于字符运算,而且按位非不能直接用于整数

* / %:
乘,除(整数为取整),取余,这些运算符不能应用于字符运算,而且取余只能用于整数.取余的返回值总是与除数符号
相同而且绝对值小于除数
+ -:
加减.对于任何数字操作数有效
<< >>:
左移和右移,只对整形操作数有效.
< > <= >=:
布尔比较符,大于,小于,小于等于,大于等于.每个运算符在条件为真时返回1,否则为0.这些操作符用于数字和字符
== !=:
布尔比较符,等于,不等于.每个运算符返回0或者1,对于所有的操作数类型有效
eq ne:
布尔比较符,等于和不等于,只用于字符串的比较
&:
按位与,只对整形数有效
^:
按位异或,只对整形数有效
|:
按位或,只对整形数有效
&&:
逻辑与,在所有操作数为非0时返回1.对于布尔值和数字操作数有效
||
逻辑或,在所有操作数为0时才返回0.对于布尔值和数字操作数有效
x?y:z
三元运算符,如果x为非0,返回y,否则返回z,x必须为布尔值或者为数字操作数

举例:
expr 4*2 < 7  返回0
The &&, ||, and ?: operators have ``lazy evaluation'', just as in C, which means that operands are not evaluated if they are not needed to determine the outcome. For example, in the command

expr {$v?$a:$b}:该表达式只解析一部分数值,即v,a和b的其中之一

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

abs(arg):返回绝对值

acos(arg):返回角度值,范围(-1,1)

asin(arg):返回角度值,范围(-1,1)

atan(arg):返回角度值

atan2(y, x):返回角度值

ceil(arg):返回大于当前值的最小整数值,以小数形式表示

cos(arg):返回角度的cos值

cosh(arg):
    返回角度的双曲cos值.
    
double(arg):将数值转换为float类型值

exp(arg):返回e的整数次幂,e=2.71828182846    

floor(arg):返回小于数字操作数的最大整数值

fmod(x, y):返回x/y的整数部分以浮点型表示

hypot(x, y):返回直角三角形的斜边值

int(arg):将数值转换为int类型值

log(arg):返回自然对数值,以e为底

log10(arg):返回对数值,以10为底

pow(x, y):返回x的y次幂

rand():返回在(0,1)之间的伪随机浮点数

round(arg):返回整型值

sin(arg):返回角度的sin值

sinh(arg):返回角度的双曲sin值

sqrt(arg):返回arg的根

srand(arg):输入arg作为随机种子,返回根据该种子产生的随机数

tan(arg):返回角度的tan值

tanh(arg):返回角度的双曲tan值

wide(arg):将arg转换为一个最少64bit的整形数

类型,溢出和精度:
对于tcl,所有涉及int类型数按c的long int处理,所有涉及浮点类型数按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.

字符串操作:
字符串被用于作为比较运算的操作数,尽管在有些情况也被用来当做整形和浮点型来做比较运算,eq和ne这些情况除外.如果比较的两个操作数一个是字符串而另一个为数字,则数字操作数被转换为字符串并且使用c函数sprintf调整格式,以%d表示整形,%g表示浮点型。比如:
expr {"0x03" > "2"} ,expr {"0y" < "0x12"} 都返回1.第一个比较使用数字比较即可完成,第二个标胶需要将0x12转换为18才能进行.因为tcl 总是倾向于以数字来处理值,对于字符串比较,使用==并不是总是有效的;最好使用eq或者ne,或者string命令。

性能考虑
以{}来界定各种参数是一个相对快速和较小存储开销的方式.这使tcl的以字节码方式编译器产生最好的程序代码.如上所述,表达式一般被替换两次:第一次是tcl解析器,第二次是expr命令,例如:
set a 3
set b {$a+2}
expr $b*4
结果返回11,而不是4的倍数.这是因为tcl解析器先将b解析为$a+2,之后expr将按这个解析后的表达式进行计算: $a+2*4
大多数的表达式不需要第二次替换.这些表达式可以通过{}进行界定,或者本身不需要替换。然而因为一些没有{}界定的表达式需要两次替换,bytecode编译器必须进行多次的探测来能处理这种情况。包含命令但没有{}界定的表达式的替换代价最大。这些表达式必须在每次执行时重新产生新的代码才能计算成功

举例
定义一个过程来计算一个有趣的数学函数:
proc calc {x y} {
    expr { ($x*$x - $y*$y) / exp($x*$x + $y*$y) }
}
将极坐标转换为直角坐标:
# convert from ($radius,$angle)
set x [expr { $radius * cos($angle) }]
set y [expr { $radius * sin($angle) }]

将直角坐标转换为极坐标:
# convert from ($x,$y)
set radius [expr { hypot($y, $x) }]
set angle  [expr { atan2($y, $x) }]

打印描述两个字符串值彼此间关系的信息:
puts "a and b are [expr {$a eq $b ? {equal} : {different}}]"

检测环境变量是否定义,并设置布尔值:
set isTrue [expr {
    [info exists ::env(SOME_ENV_VAR)] &&
    [string is true -strict $::env(SOME_ENV_VAR)]
}]

随机产生范围在0-99之间的数值:
set randNum [expr int(100*random())]


转载:http://blog.chinaunix.net/uid-7262118-id-71404.html
阅读(2053) | 评论(0) | 转发(0) |
0

上一篇:没有了

下一篇:llength

给主人留下些什么吧!~~