expr - 求一個表示式的值
expr arg ?
arg arg ...?
連線(concatenate)所有
arg
(在它們中間新增分隔符空格),把結果作為一個Tcl
表示式來求值(evaluate)並返回結果。在
Tcl
表示式中允許的運算子式在
C
表示式中允許的運算子的一個子集,並且它們與相應的
C
運算子有相同意義和優先順序。表示式幾乎總是產生一個數值結果(整數或浮點數的值)。例如,表示式
求值出 14.2. Tcl 表示式與 C
表示式在運算元指定的方式上有區別。還有,Tcl
表示式支援非數值運算子和字串比較。
一個 Tcl
表示式由運算子、運算元和括號的組合構成。在運算子、運算元和括號之間可使用白空格;它被表示式的指令所忽略。指定整數值可以使用十進位制(通常的情況)、八進位制(如果運算元的第一個字元是
0)、或十六進位制(如果運算元的前兩個字元是
0x)。如果一個運算元沒有上述的整數格式,則如果可能的話把它作為浮點數對待。指定浮點數可以使用任何遵從
ANSI 的 C
編譯器可接受方式(除了在多數安裝(installation)中不允許
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 + $a 6.1
expr 2 + "$a.$b" 5.6
expr 4*[llength "6 2"] 8
expr {{word one} < "word $a"} 0
下面列出了有效的運算子,用優先順序的降序分組:
- - + ~ !
- 一元(Unary,也譯為單目)減,一元加,位(bit-wise)
NOT,邏輯
NOT。這些運算子不能提供給字串運算元,並且位
NOT 只能提供給整數。
- * / %
- 乘,除,求餘。這些運算子不能提供給字串運算元,並且求餘隻能提供給整數。餘數將總是與除數有相同的符號並且絕對值小於除數。
- + -
- 加和減。對任何數值運算元均有效。
- << >>
- 左移和右移。只對整數運算元有效。一右移總是傳播(propagate)符號位。
- < > <= >=
- Boolean
小於,大於,小於等於,大於等於。如果條件是真則每個運算子產生
1,否則
0。這些運算子可以象提供給數值運算元一樣提供給字串,在這種情況下使用字串比較。
- == !=
- Boolean
等於和不等於。每個運算子產生一個零/一結果。對所有運算元型別有效。
- &
- 位與。只對整數運算元有效。
- ^
- 位異或。只對整數運算元有效。
- |
- 位或。只對整數運算元有效。
- &&
- 邏輯與。如果兩個運算元都是非零則生成一個
1,否則生成 0。只對
boolean
和數值(整數或浮點數)運算元有效。
- ||
- 邏輯或。如果兩個運算元都是零則生成一個
0,否則生成 1。只對
boolean
和數值(整數或浮點數)運算元有效。
-
x?y:z
- If-then-else,如同 C
語言那樣。如果 x
求值為非零,則結果是
y
的值。否則結果是 z
的值。
x運算元必須是一個數值值。
參見 C
手冊來得到對每個運算子的生成結果的更詳細的描述。所有相同的優先順序的二元運算子從左至右的組合(group)。例如,命令
返回 0.
&&,
||, 和
?:
運算子“惰性求值”,如同
C
語言那樣,這意味著如果運算元對確定結果不是必須的則不被求值。例如,命令
中實際上只有
[a] 或
[b]中的一個將被求值,依賴於
$v
的值。注意,這隻在整個表示式被包圍在花括號中時是真的;否則
Tcl 分析器將在呼叫
expr
命令之前求值
[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]。 .TP
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)
- 計算一個直角三角形的斜邊的長度(x*x+y*y)。
-
int(arg)
- 如果 arg
是一個整數值,返回
arg,否則透過擷取arg
(的整數部分)來把它轉換成整數並返回轉換後的值。
-
log(arg)
- 返回 arg
的自然對數。 Arg
必須是正數值。
-
log10(arg)
- 返回 arg 的以10
為底的對數(常用對數)。
Arg必須是正數值。
-
pow(x, y)
- 計算 x 的 y
次冪。如果 x
是負數, y
必須是一個整數值。
- rand()
- 返回一個大於等於零且小於
1
的一個(隨機)浮點數,這個範圍用數學術語是區間[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 ()
定義增補的函式。
所有涉及整數的內部運算用
C 型別
long
處置。並且所有涉及浮點數的內部運算用
C 型別
double
處置。當把一個字串轉換成一個浮點數的時候,若檢測到指數溢位則導致一個
Tcl
錯誤。對於從字串轉換成整數,溢位檢測依賴於在本地
C
庫中的一些例程的行為,所以它應被作為不可靠的來看待。在任何情況下,對中間結果通常不能可靠的檢測整數的上溢和下溢。浮點數上溢和下溢的檢測通常達到由硬體支援的程度,普遍非常可靠。
整數,浮點數、和字串的內部表示之間的轉換按需要自動完成。對於算術計算,在浮點數介入之前使用整數,此後使用浮點數。例如,
返回 1,而
expr 5 / 4.0
expr 5 / ( [string length "abcd"] + 0.0 )
都返回 1.25。
返回的浮點值總是帶著一個“
.”或一個
e
所以它們看起來不象整數值。例如,
返回
4.0, 而不是
4.
字串可被用做比較運算子的運算元,儘管表示式求值器儘可能的嘗試著作為整數或浮點數來做比較。如果一個比較的運算元中的一個是字串而其他是數值值,數值運算元被轉換回字串,對整數值使用
C
sprintf 格式指定符
%d
,對浮點數值使用
%g。例如,命令
expr {"0x03" > "2"}
expr {"0y" < "0x12"}
都返回
1。做第一個比較使用了整數比較,而做第二個比較在把第二個運算元轉換成字串
18之後使用了字串比較。因為
Tcl
趨向於盡可能的把值作為數值對待,在你事實上想進行字串比較並且運算子的值可以是任意的的時候使用象
==
這樣的運算子通常不是個好主意;在這種情況下最好使用
string命令。
要得到最快的速度和最小的儲存需求,就要把表示式包圍在花括號中。這允許
Tcl
位元組碼編譯器生成最好的程式碼。
象上面所提及的那樣,表示式被替換兩次:
一次由 Tcl
直譯器,一次由
expr
命令。例如,命令
set a 3
set b {$a + 2}
expr $b*4
返回 11,而不是 4
的倍數。這是因為 Tcl
分析器將首先把變數
b替換成
$a + 2,接著
expr 命令將求值表示式
$a + 2*4。
多數表示式不需要兩輪替換。要它們被包圍在花括號中,要麼它們的變數和命令替換生成數值或本身不需要替換的字串。但是,因為一些未用化括號包圍起來的表示式需要兩輪替換,位元組碼編譯器必須散佈(emit)額外的指令來處理這些情況。對於未用化括號包圍起來的表示式,代價最高昂的程式碼是包含命令替換的程式碼。必須透過在每次執行這個表示式時生成新的程式碼來實現這些表示式。
arithmetic, boolean, compare, expression, fuzzy comparison
寒蟬退士
2001/07/22
http://cmpp.linuxforum.net
本頁面中文版由中文 man
手冊頁計劃提供。
中文 man 手冊頁計劃:
https://github.com/man-pages-zh/manpages-zh