expr(3tcl) Tcl Built-In Commands expr(3tcl)

expr - 求一個表示式的值

總覽 SYNOPSIS

expr arg ?arg arg ...?

描述 DESCRIPTION

連線(concatenate)所有 arg (在它們中間新增分隔符空格),把結果作為一個Tcl 表示式來求值(evaluate)並返回結果。在 Tcl 表示式中允許的運算子式在 C 表示式中允許的運算子的一個子集,並且它們與相應的 C 運算子有相同意義和優先順序。表示式幾乎總是產生一個數值結果(整數或浮點數的值)。例如,表示式

expr 8.2 + 6
求值出 14.2. Tcl 表示式與 C 表示式在運算元指定的方式上有區別。還有,Tcl 表示式支援非數值運算子和字串比較。

運算元 OPERANDS

一個 Tcl 表示式由運算子、運算元和括號的組合構成。在運算子、運算元和括號之間可使用白空格;它被表示式的指令所忽略。指定整數值可以使用十進位制(通常的情況)、八進位制(如果運算元的第一個字元是 0)、或十六進位制(如果運算元的前兩個字元是 0x)。如果一個運算元沒有上述的整數格式,則如果可能的話把它作為浮點數對待。指定浮點數可以使用任何遵從 ANSI 的 C 編譯器可接受方式(除了在多數安裝(installation)中不允許 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 + $a	6.1
expr 2 + "$a.$b"	5.6
expr 4*[llength "6 2"]	8
expr {{word one} < "word $a"}	0

運算子 OPERATORS

下面列出了有效的運算子,用優先順序的降序分組:

-  +  ~  !
一元(Unary,也譯為單目)減,一元加,位(bit-wise) NOT,邏輯 NOT。這些運算子不能提供給字串運算元,並且位 NOT 只能提供給整數。
*  /  %
乘,除,求餘。這些運算子不能提供給字串運算元,並且求餘隻能提供給整數。餘數將總是與除數有相同的符號並且絕對值小於除數。
+  -
加和減。對任何數值運算元均有效。
<<  >>
左移和右移。只對整數運算元有效。一右移總是傳播(propagate)符號位。
<  >  <=  >=
Boolean 小於,大於,小於等於,大於等於。如果條件是真則每個運算子產生 1,否則 0。這些運算子可以象提供給數值運算元一樣提供給字串,在這種情況下使用字串比較。
==  !=
Boolean 等於和不等於。每個運算子產生一個零/一結果。對所有運算元型別有效。
&
位與。只對整數運算元有效。
^
位異或。只對整數運算元有效。
|
位或。只對整數運算元有效。
&&
邏輯與。如果兩個運算元都是非零則生成一個 1,否則生成 0。只對 boolean 和數值(整數或浮點數)運算元有效。
||
邏輯或。如果兩個運算元都是零則生成一個 0,否則生成 1。只對 boolean 和數值(整數或浮點數)運算元有效。
If-then-else,如同 C 語言那樣。如果 x 求值為非零,則結果是 y的值。否則結果是 z 的值。x運算元必須是一個數值值。

參見 C 手冊來得到對每個運算子的生成結果的更詳細的描述。所有相同的優先順序的二元運算子從左至右的組合(group)。例如,命令

expr 4*2 < 7
返回 0.

&&, ||, 和 ?: 運算子“惰性求值”,如同 C 語言那樣,這意味著如果運算元對確定結果不是必須的則不被求值。例如,命令

expr {$v ? [a] : [b]}
中實際上只有 [a][b]中的一個將被求值,依賴於 $v 的值。注意,這隻在整個表示式被包圍在花括號中時是真的;否則 Tcl 分析器將在呼叫 expr 命令之前求值 [a][b] 二者。

數學函式 MATH FUNCTIONS

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
返回 arg 的絕對值。Arg可以要麼式整數要麼是浮點數,並且結果以同樣的形式返回。
返回 arg 的反餘弦,值域是 [0,pi] 弧度。Arg的定義域是 [-1,1]。 .TP asin(arg) 返回 arg 的反正弦,值域是 [-pi/2,pi/2] 弧度。Arg 的定義域是 [-1,1]。
返回 arg 的反正切,值域是 [-pi/2,pi/2] 弧度。
返回 y/x的反正切,值域是 [-pi,pi] 和,xy 不能都是 0。
返回不小於 arg 的最小的整數值。
返回 arg 的餘弦,單位是弧度。
返回 arg 的雙曲餘弦,如果結果導致溢位,返回一個錯誤。
如果 arg 是一個浮點值,返回 arg;否則把 arg 轉換成浮點數並返回轉換後的值。
返回 arg 的指數,定義為 e**arg。如果結果導致溢位,返回一個錯誤。
返回不大於 arg 的最大整數值。
返回 x 除以 y 得到的浮點餘數。如果 y 是 0,返回一個錯誤。
計算一個直角三角形的斜邊的長度(x*x+y*y)。
如果 arg 是一個整數值,返回 arg,否則透過擷取arg (的整數部分)來把它轉換成整數並返回轉換後的值。
返回 arg 的自然對數。Arg 必須是正數值。
返回 arg 的以10 為底的對數(常用對數)。Arg必須是正數值。
計算 xy 次冪。如果 x 是負數,y 必須是一個整數值。
返回一個大於等於零且小於 1 的一個(隨機)浮點數,這個範圍用數學術語是區間[0,1)。種子來自機器的內部時鐘或用 srand 函式人為設定。
如果 arg 是一個整數,返回 arg,否則透過四捨五入把 arg 轉換成整數並返回轉換後的值。
返回 arg 的正弦,單位是弧度。
返回 arg 的雙曲正弦。如果結果導致溢位,返回一個錯誤。
返回 arg 的開方。Arg 必須是非負數。

arg 必須是一個整數,它被用於重置隨機數生成器的種子。返回用這個種子生成的第一個隨機數。每個直譯器都有它自己的種子。
返回 arg 的正切。單位是弧度。
返回 arg 的雙曲正切。

除了這些預定義的函式之外,應用可以使用 Tcl_CreateMathFunc () 定義增補的函式。

型別 TYPES, 溢位 OVERFLOW, 和 精度 PRECISION

所有涉及整數的內部運算用 C 型別 long處置。並且所有涉及浮點數的內部運算用 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.

字串操作 STRING OPERATIONS

字串可被用做比較運算子的運算元,儘管表示式求值器儘可能的嘗試著作為整數或浮點數來做比較。如果一個比較的運算元中的一個是字串而其他是數值值,數值運算元被轉換回字串,對整數值使用 C sprintf 格式指定符 %d ,對浮點數值使用 %g。例如,命令

expr {"0x03" > "2"}
expr {"0y" < "0x12"}
都返回 1。做第一個比較使用了整數比較,而做第二個比較在把第二個運算元轉換成字串 18之後使用了字串比較。因為 Tcl 趨向於盡可能的把值作為數值對待,在你事實上想進行字串比較並且運算子的值可以是任意的的時候使用象 == 這樣的運算子通常不是個好主意;在這種情況下最好使用 string命令。

效能的考慮 PERFORMANCE CONSIDERATIONS

要得到最快的速度和最小的儲存需求,就要把表示式包圍在花括號中。這允許 Tcl 位元組碼編譯器生成最好的程式碼。

象上面所提及的那樣,表示式被替換兩次: 一次由 Tcl 直譯器,一次由 expr 命令。例如,命令

set a 3
set b {$a + 2}
expr $b*4
返回 11,而不是 4 的倍數。這是因為 Tcl 分析器將首先把變數 b替換成 $a + 2,接著 expr 命令將求值表示式 $a + 2*4

多數表示式不需要兩輪替換。要它們被包圍在花括號中,要麼它們的變數和命令替換生成數值或本身不需要替換的字串。但是,因為一些未用化括號包圍起來的表示式需要兩輪替換,位元組碼編譯器必須散佈(emit)額外的指令來處理這些情況。對於未用化括號包圍起來的表示式,代價最高昂的程式碼是包含命令替換的程式碼。必須透過在每次執行這個表示式時生成新的程式碼來實現這些表示式。

關鍵字 KEYWORDS

arithmetic, boolean, compare, expression, fuzzy comparison

寒蟬退士

2001/07/22

《中國 Linux 論壇 man 手冊頁翻譯計劃》:

http://cmpp.linuxforum.net

本頁面中文版由中文 man 手冊頁計劃提供。
中文 man 手冊頁計劃:https://github.com/man-pages-zh/manpages-zh

8.3 Tcl