TCL脚本语言-4-数学计算,怎么这么烦

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

数学计算,怎么这么烦?

前面的快速入门教程里面已经提到了expr命令,TCL中所有的数学计算都是通过expr 命令来完成的。这一点和其他语言非常的不同,例如Python中:

>>> from math import *

>>> pi

3.1415926535897931

>>> print cos(pi/4)*2 , sqrt(2)

1.41421356237 1.41421356237

>>>

Python里面的表达式是非常直观的,其他语言例如VBScript等也是如此。但是TCL中,即使是计算两个数字相加,都得使用expr命令:

set a 100; set b 200

puts “a+b = $a+$b”;#输出a+b = 100+200

puts “a+b = [expr $a+$b]”;#输出a+b = 300

TCL中,expr加上一堆的$符号,方括号等字符,最简单的表达式,看起来都是非常不爽。这对于刚刚接触TCL的人来说,简直是一件无法忍受的事情,当初我也是这么认为的。后来在网上发现有人还真的通过扩展,在TCL实现类似Python的语法,比如原来的:

set a [expr $a+$b]

可以写成:

a = $a+$b

至于是怎么实现的,我们后面会进行详细的分析。但是我觉得,既然选择了TCL,就要习惯其用法;要么当初就选择Python拉到,所以我不赞成上面的这种改进。而且习惯了TCL 之后,也没有觉得它没有我们想象中的那么不方便。

语法描述

expr命令是TCL的核心命令之一,其语法格如下:

expr arg ?arg arg ...?

该命令可以有一个或者多个参数,在执行的时候,把所有的参数连接起来成为一个数学

表达式字符串,然后计算这个表达式,计算结果作为命令结果返回。下面两条命令写法不一样,但是结果一样:

set PI 3.1415926535897932

set sqrt2_1 [expr "cos($PI/4)*2"]

set sqrt2_2 [expr cos ( $PI / 4 ) * 2]

puts "sqrt2_1 = $sqrt2_1\nsqrt2_2 = $sqrt2_2"

两个expr命令,第一个命令只有一个参数(所有的东西都被引号括起来),第二个则拆开了,参数个数一堆。但是计算结果都是一样的:

sqrt2_1 = 1.41421356237

sqrt2_2 = 1.41421356237

操作符

expr命令所支持的计算操作符是C语言中操作符的一个子集。并且写法和优先级也和C 语言完全一致。除了数学计算操作符之外,expr还支持字符串的比较操作。下面是expr支持的操作符,按照优先级从高到低排列:

操作符含义说明

- + ~ !单目取负;单目正号;按位取反(not);逻辑取反;

* / %乘法;除法;取余;

+ -加法;减法;

<< >>向左移位,向右移位;

< > <= >=比较操作符,小于、大于、小于等于、大于等于;结果1表示true,0表示false;这几个操作符可以作用于字符串,进行大小写敏感的比较;

== !=比较是否相等:等于、不等于;结果1和0分别表示true和false。可以作用于所有类型的操作数;

eq ne 字符串的比较:等于、不等于;结果1和0表示true和false。进行计算的时候,其操作数都被当成字符串进行比较。

&按位与操作(AND),只能够作用于整数;^按位异或操作(XOR),只能构作用于整数;|按位或操作(OR),只能构作用于整数;

&& 逻辑与操作(AND),只有两个操作数都非零的时候,结果才是1,否则为0。只能够作用于boolean类型或者数字类型。

||逻辑或操作(OR),只有两个操作数都为0的时候,结果才是0,否则为1;只能够作用于boolean或者数字类型。

x?y:z If-then-else操作,和C中的比较类似。如果x计算得出非零值,那么y的值就

是表达式的结果;否则,z的值就是表达式的结果。x的值必须是一个数值或者

boolean值。

其中,&&,||,x?y:z三个操作符和C语言中一样,会进行布尔短路计算:当表达式计算了一部分就知道整个结果的时候,那么其他部分就不会计算了。例如:

proc a { t } {

puts "PROC A . t=$t"

return [expr $t+1]

}

puts [expr {[a 100]>100 ? [a 200] : [a 300]}]

上面的代码执行输出为:

PROC A . t=100

PROC A . t=200

201

可以看到,[a 300]根本就不会执行。但是如果这样写:

puts [expr “[a 100]>100 ? [a 200] : [a 300]”]

把expr后面得表达式用双引号括起来,结果就不一样了,a命令会执行三次!为什么,大家都是高手,自己分析。

操作数

数学表达式中肯定离不开操作数,操作数是操作符进行运算的对象(这简直是废话)。expr命令在解析操作数的时候,依照如下顺序进行:

1.整数。expr首先判断是否是整数,expr表达式中的整数可以表示成普通的十进制,

也可以表示成8进制(用0开始)和十六进制(用0x开始)。

2.浮点数。如果操作数不具备上面描述的整数的格式,那么就试图将其解释成浮点数。

expr表达式中的浮点数和ANSI-C中的浮点数格式类似,后面不能够加上f,F,L,l这

样的后缀,例如2.1,3.,3.2E1.0等都是正确的浮点数。

3.字符串。如果既不能够解释成整数,也不能够解释成浮点数,那么就只有当成字符

串了。

使用整数注意范围,8.4版本的TCL中,整数的最大范围是0x7FFFFFFFFFFFFFFF,也就是说,使用8个字节来表示的。但是8.3版本的TCL中,整数是32个字节来表示。

expr的操作数可以是如下的形式:

1.一个数值;

2.$varName格式的变量引用;

相关文档
最新文档