文章目錄
第五章 瘋狂Caché 運算符和表達式(二)
算術運算符
算術運算符將其操作數解釋爲數值並生成數值結果。在對字符串進行操作時,算術運算符會根據“字符串到數字轉換”一節中描述的規則,將該字符串視爲其數值。
一元正運算符(+)
一元正運算符(+
)對其單個操作數進行數值解釋。如果其操作數有字符串值,則將其轉換爲數字值。它通過將字符串的字符順序解析爲數字來實現這一點,直到它遇到無效字符。然後,它返回字符串的任何前導部分是格式良好的數字。例如:
WRITE + "32 dollars and 64 cents" // 32
32
```java
如果字符串沒有前導數字字符,則一元正運算符會將操作數賦給零值。例如:
```java
WRITE + "Thirty-two dollars and 64 cents" // 0
0
一元正運算符對數值沒有影響。它不會改變正數或負數的符號。例如:
SET x = -23
WRITE " x: ", x,! // -23
WRITE "+x: ",+x,! // -23
x: -23
+x: -23
一元負運算符(-)
一元負運算符(-
)反轉數值解釋的操作數的符號。例如:
SET x = -60
WRITE " x: ", x,! // -60
WRITE "-x: ",-x,! // 60
x: -60
-x: 60
如果其操作數具有字符串值,則一元負運算符在反轉其符號之前將其解釋爲數字值。此數值解釋與上述一元正運算符執行的數字解釋完全相同。例如:
SET x = -23
WRITE -"32 dollars and 64 cents" // -32
-32
CachéObjectScript使一元負運算符優先於二元算術運算符。CachéObjectScript首先掃描數字表達式並執行任何一元負操作。然後,CachéObjectScript對表達式求值並生成結果。
在下面的示例中,CachéObjectScript掃描字符串並遇到數值2,然後停止。然後,它將一元負運算符應用於該值,並使用連接運算符(_
)將值“RATS”
從第二個字符串連接到數字值。
WRITE -"2Cats"_"Rats" // -2Rats
-2Rats
要返回數值表達式的絕對值,請使用$ZABS
函數。
DHC-APP 3d1>w $zabs(-3)
3
DHC-APP 3d1>w $zabs(+3)
3
加法運算符(+)
加法運算符產生兩個數值解釋的操作數之和。它使用任何前導有效數字字符作爲操作數的數字值,並生成操作數的數字值之和的值。
下面的示例對兩個數字文字執行加法:
WRITE 2936.22 + 301.45
3237.67
下面的示例對兩個本地定義的變量執行加法:
SET x = 4
SET y = 5
WRITE "x + y = ",x + y
x + y = 9
下面的示例對具有前導數字的兩個操作數執行字符串算術,並將結果數字相加:
WRITE "4 Motorcycles" + "5 bicycles"
9
下面的示例說明數值計算的操作數上的前導零不會影響運算符生成的結果:
WRITE "007" + 10
17
減法運算符(-)
減法運算符產生兩個數值解釋的操作數之間的差值。它將任何前導的有效數字字符解釋爲操作數的數字值,並生成減法後的餘數的值。
下面的示例對兩個數字文字執行減法:
WRITE 2936.22 - 301.45
2634.77
下面的示例對兩個本地定義的變量執行減法:
SET x = 4
SET y = 5
WRITE "x - y = ",x - y
-1
下面的示例對具有前導數字的兩個操作數執行字符串算術,減去結果數字:
WRITE "8 apples" - "4 oranges"
4
如果操作數沒有前導數字字符,則CachéObjectScript假定其值爲零。例如:
WRITE "8 apples" - "four oranges" // 8
8
乘法運算符(*)
二進制乘法產生兩個數值解釋的操作數的乘積。它使用任何前導數字字符作爲操作數的數字值,並生成乘積結果。
下面的示例對兩個數字文字執行乘法:
WRITE 9 * 5.5
49.5
下面的示例對兩個本地定義的變量執行乘法:
SET x = 4
SET y = 5
WRITE x * y
20
下面的示例對具有前導數字的兩個操作數執行字符串算術,並將結果數字相乘:
WRITE "8 apples" * "4 oranges"
32
如果操作數沒有前導數字字符,則二進制乘法會爲其賦值爲零。
WRITE "8 apples"*"four oranges"
0
除法運算符(/)
二進制除法產生將兩個數值解釋的操作數相除的結果。它使用任何前導數字字符作爲操作數和乘積的數字值,結果就是商。
下面的示例對兩個數字文字執行除法:
WRITE 9 / 5.5
1.636363636363636364
下面的示例對兩個本地定義的變量執行除法:
SET x = 4
SET y = 5
WRITE x / y
.8
下面的示例對具有前導數字的兩個操作數執行字符串算術,並將結果數字相除:
WRITE "8 apples" / "4 oranges"
2
如果操作數沒有前導數字字符,則二進制除法假定其值爲零。例如:
WRITE "eight apples" / "4 oranges"
0
WRITE "8 apples"/"four oranges"
DHC-APP 3d1> WRITE "8 apples"/"four oranges"
WRITE "8 apples"/"four oranges"
^
<DIVIDE>^PHA.TEST.ObjectScript.1
請注意,這些操作中的第二個是無效的。不允許將數字除以零。CachéObjectScript返回<Divide>
錯誤消息。
求冪運算符(**
)
求冪運算符產生左操作數的指數化值,該值是右操作數的冪。
-
0 ** 0
:0的零冪等於0。但是,如果任一操作數是IEEE雙精度數(例如,0 ** $DOUBLE(0)
或$DOUBLE(0) ** 0)
,則零的零冪爲1。 -
0**n
:0的任意正數n的冪是0。這包括0**$DOUBLE(“INF”)
。嘗試將0取負數的冪會導致錯誤:Caché負數會生成<非法值>
錯誤;$DOUBLE
負數會生成<Divide>
錯誤。 -
Num**0
:任何非零數(正數或負數)的零冪都是1。這包括$DOUBLE(“INF”)**0
。 -
1**n
:1的任意數字的冪(正、負或零)是1。 -
-1**n
:-1的0次方等於1。-1的1次方或者-1次方等於-1。 -
Num**n
:正數(整數或小數)乘以任意冪(整數或分數、正或負)返回正數。 -
-num**n
:負數(整數或小數)乘以偶數(正或負)的冪將返回正數。負數(整數或小數)乘以奇數(正或負)的冪將返回負數。 -
-num**.N
:嘗試將負數提高到小數的冪會導致<非法值>
錯誤。 -
$DOUBLE(\“INF\”)**n
:無窮大數字(正數或負數)的0次方是1。無限數(正數或負數)與任何正數(整數、小數或INF
)的冪都是INF
。無限數(正數或負數)與任何負數(整數、小數或INF
)的冪均爲0。 -
$DOUBLE(“NaN”)
:求冪運算符兩側的NaN
始終返NaN
,而不考慮另一個操作數的值。
非常大的指數可能會導致上溢值和下溢值:
-
Num**nnn
:大於1且具有較大正指數值的正數或負數(如9**153
或-9.2**152)
會生成<MAXNUMBER>
錯誤。 -
Num**-nnn
:大於1且具有較大負指數值的正數或負數(如9**-135
或-9.2**-134
)返回0。 -
.num**nnn
:小於1且具有較大正指數值(例如.22**196
或-.2**184
)的正數或負數返回0。 -
.Num**-nnn
:小於1且具有較大負指數值的正數或負數(如.22**-196
或-.2**-184
)會生成<MAXNUMBER>
錯誤。
超過Caché number支持的最大值的指數要麼會發出<MAXNUMBER>
錯誤,要麼會自動轉換爲IEEE雙精度浮點數。
此自動轉換是通過使用%SYSTEM.Process
類的TruncateOverflow()
方法(基於每個進程)或Config.Miscellous
類的TruncateOverflow
屬性(基於系統範圍)指定的。
以下示例對兩個數值文字執行冪運算:
WRITE "9 ** 2 = ",9 ** 2,!
WRITE "9 ** -2 = ",9 ** -2,!
WRITE "9 ** 2.5 = ",9 ** 2.5,!
9 ** 2 = 81
9 ** -2 = .01234567901234567901
9 ** 2.5 = 242.9999999994422343
下面的示例對兩個本地定義的變量執行冪運算:
SET x = 4, y = 3
WRITE "x ** y = ",x ** y,!
64
下面的示例執行字符串算術。求冪使用任何前導數字字符作爲操作數的值,並生成結果。
WRITE "4 apples" ** "3 oranges"
64
如果操作數沒有前導數字字符,則求冪假定其值爲零。
下面的示例演示如何使用求冪來查找數字的平方根。
WRITE 256 ** .5 // 16
16
還可以使用$zpower
函數執行冪運算。
DHC-APP>w $ZPOWER(2,2)
4
DHC-APP>w 16**0.5**0.5
2
DHC-APP>w 16**0.25
1.999999999999999883
整數除法運算符(\
)
整數除運算符產生左操作數除以右操作數的整數結果。它不返回餘數,也不四捨五入結果。
下面的示例對兩個整數操作數執行整數除法。CachéObjectScript不返回數字的小數部分:
WRITE "355 \ 113 = ", 355 \ 113
355 \ 113 = 3
下面的示例執行字符串算術。INTEGER DIVIDE
使用任何前導數字字符作爲操作數的值,並生成整數結果。
WRITE "8 Apples" \ "3.1 oranges"
2
如果操作數沒有前導數字字符,則CachéObjectScript假定其值爲零。如果嘗試使用零值除數進行整數除法,則CachéObjectScript將返回<divide>
錯誤。
取餘數(#
)
模運算符在兩個數值解釋的操作數上產生算術模運算符的值。當兩個操作數爲正時,模運算是左操作數整數除以右操作數的餘數。
以下示例對數值文字執行模運算,並返回餘數:
WRITE "37 # 10 = ",37 # 10,!
WRITE "12.5 # 3.2 = ",12.5 # 3.2,!
37 # 10 = 7
12.5 # 3.2 = 2.9
下面的示例執行字符串算術。當對字符串進行操作時,它們在應用模運算符之前被轉換爲數字值(根據變量鍵入和轉換一節中描述的值)。因此,以下兩個表達式等效:
WRITE "8 apples" # "3 oranges",! // 2
WRITE 8 # 3 // 2
2
2
因爲Caché將沒有前導數字字符的字符串求值爲零,所以這種右操作數會產生<Divide>
錯誤。
邏輯比較運算符
邏輯比較運算符會比較它們的操作數的值,並返回布爾值:TRUE(1)
或FALSE(0)
。
一元運算符Not
一元NOT反轉布爾操作數的真值。如果操作數爲TRUE(1)
,則UNARY NOT爲其賦值FALSE(0)
。如果操作數爲FALSE(0)
,則UNARY NOT爲其賦值TRUE(1)
。
例如,以下語句生成的結果爲FALSE(0)
:
SET x=0
WRITE x
0
而以下語句產生的結果爲true(1)
。
SET x=0
WRITE 'x
1
帶有比較運算符的一元NOT將顛倒其執行的操作的意義。它有效地反轉了操作的結果。例如,以下語句顯示FALSE(0)
的結果:
WRITE 3>5
0
但是,以下語句顯示TRUE(1)
的結果:
WRITE 3'>5
1
優先運算符和邏輯運算符
由於CachéObjectScript對運算符執行從左到右的嚴格求值,因此涉及其他運算符的邏輯比較必須使用括號對運算進行分組,才能獲得所需的優先級。例如,可能需要邏輯二進制或(!
)。在以下程序中測試以返回TRUE(1)
:
SET x=1,y=0
IF x=1 ! y=0 {WRITE "TRUE"}
ELSE {WRITE "FALSE" }
FALSE
但是,要正確執行此邏輯比較,必須使用括號來嵌套其他操作。以下示例給出了預期結果:
SET x=1,y=0
IF (x=1) ! (y=0) {WRITE "TRUE"}
ELSE {WRITE "FALSE" }
TRUE
And與
並測試其兩個操作數是否都具有TRUE(1)
真值。如果兩個操作數都爲true(即在數值計算時具有非零值),則CachéObjectScript會生成值true(1)
。否則,CachéObjectScript將生成值False(0)
。
二進制AND有兩種形式:&
和&&
。
-
&
運算符計算兩個操作數,如果其中一個操作數的計算結果爲零,則返回值FALSE(0)
。否則,它返回值true(1)
。 -
&&
運算符計算左操作數,如果計算結果爲零,則返回值FALSE(0)
。只有當左操作數非零時,&&
運算符纔會計算右操作數。如果右操作數的計算結果爲零,則返回值FALSE(0)
。否則,它返回值true(1)
。
下面的示例將兩個非零值操作數求值爲TRUE,並生成值TRUE(1)
。
SET A=-4,B=1
WRITE A&B // TRUE (1)
1
SET A=-4,B=1
WRITE A&&B // TRUE (1)
1
下面的示例計算一個TRUE和一個FALSE操作數,並生成FALSE(0)
值。
SET A=1,B=0
WRITE "A = ",A,!
WRITE "B = ",B,!
WRITE "A&B = ",A&B,! // FALSE (0)
SET A=1,B=0
WRITE "A&&B = ",A&&B,! // FALSE (0)
A = 1
B = 0
A&B = 0
A&&B = 0
下面的示例顯示了“&
”運算符和“&&
”運算符之間的區別。在這些示例中,左操作數的計算結果爲FALSE(0)
,並且未定義右操作數。“&
”和“&&
”運算符對此情況的響應不同:
- “
&
”運算符嘗試計算這兩個操作數,但失敗,並顯示<unfined>
錯誤。
TRY {
KILL B
SET A=0
WRITE "variable A defined?: ",$DATA(A),!
WRITE "variable B defined?: ",$DATA(B),!
WRITE A&B
WRITE !,"Success"
RETURN
}
CATCH exp
{
IF 1=exp.%IsA("%Exception.SystemException") {
WRITE !,"System exception",!
WRITE "Name: ",$ZCVT(exp.Name,"O","HTML"),!
WRITE "Data: ",exp.Data,!!
}
ELSE { WRITE "not a system exception"}
}
variable A defined?: 1
variable B defined?: 0
System exception
Name: <UNDEFINED>
Data: B
“&&
”運算符僅計算左操作數,並生成值FALSE(0)
。
TRY {
KILL B
SET A=0
WRITE "variable A defined?: ",$DATA(A),!
WRITE "variable B defined?: ",$DATA(B),!
WRITE A&&B
WRITE !,"Success"
RETURN
}
CATCH exp
{
IF 1=exp.%IsA("%Exception.SystemException") {
WRITE !,"System exception",!
WRITE "Name: ",$ZCVT(exp.Name,"O","HTML"),!
WRITE "Data: ",exp.Data,!!
}
ELSE { WRITE "not a system exception"}
}
variable A defined?: 1
variable B defined?: 0
0
Success
非與(NAND)
通過將一元NOT運算符與二元AND(&
)運算符配合使用,可以指定布爾NOT AND(NAND
)運算,格式如下:
operand '& operand '(operand & operand)
NOT AND運算反轉&BINARY
的真值,並將其應用於兩個操作數。當一個或兩個操作數都爲假時,它會生成值true(1)
。當兩個操作數都爲TRUE時,它會生成值FALSE。
&&二元AND運算符不能以一元NOT運算符爲前綴:不支持“‘&&
”格式。但是,支持以下格式:
'(operand && operand)
下面的示例執行兩個等效的NOT AND操作。每個操作數計算一個FALSE(0)
和一個TRUE(1)
操作數,併產生TRUE(1)
值。
SET A=0,B=1
WRITE !,A'&B // Returns 1
WRITE !,'(A&B) // Returns 1
1
1
下面的示例通過執行&&
二元AND運算,然後使用一元NOT來反轉結果,從而執行NOT AND運算。&&操作測試第一個操作數,因爲布爾值爲false(0)
,所以&&
不測試第二個操作數。一元值不反轉生成的布爾值,因此表達式返回TRUE(1)
:
SET A=0
WRITE !,'(A&&B)
1
或
如果任一操作數的值爲TRUE或兩個操作數的值都爲TRUE(1)
,則二進制或生成TRUE(1)
的結果。BINARY OR僅在兩個操作數都爲FALSE(0)
時才生成FALSE(0)
結果。
二進制或有兩種形式:!
(感嘆號)和||
(兩個豎線)。
那!
運算符對兩個操作數求值,如果兩個操作數的求值均爲零,則返回值False(0)
。否則,它返回值true(1)
。
||
運算符計算左操作數。如果左操作數的計算結果爲非零值,則||
運算符返回TRUE(1)
值,而不計算右操作數。只有當左操作數的計算結果爲零時,||
運算符纔會計算右操作數。如果右操作數的計算結果也爲零,則返回FALSE(0)
值。否則,它返回值true(1)
。
下面的示例計算兩個TRUE(非零)操作數,對它們應用二進制或,並生成TRUE結果:
SET A=5,B=7
WRITE "A!B = ",A!B,!
SET A=5,B=7
WRITE "A||B = ",A||B,!
A!B = 1
A||B = 1
下面的示例計算一個FALSE和一個TRUE操作數,對它們應用二進制或,並生成TRUE結果:
SET A=0,B=7
WRITE "A!B = ",A!B,!
SET A=0,B=7
WRITE "A||B = ",A||B,!
A!B = 1
A||B = 1
下面的示例計算兩個假操作數並生成值爲false的結果。
SET A=0,B=0
WRITE "A!B = ",A!B,!
SET A=0,B=0
WRITE "A||B = ",A||B,!
A!B = 0
A||B = 0
非或(或非)(NOR)
可以通過將Unary NOT與!一起使用來產生NOT或(NOR)運算。二進制或以下任一等效格式:
operand '! operand '(operand ! operand)
如果兩個操作數的值都爲FALSE,則NOT OR運算將產生TRUE(1)
結果。如果其中一個操作數的值爲TRUE,或者兩個操作數都爲TRUE,則NOT OR運算將生成FALSE(0)
結果。
'(operand || operand)
下面的NOT或示例計算兩個假操作數並生成TRUE結果。
SET A=0,B=0
WRITE "A'!B = ",A'!B
A'!B = 1
SET A=0,B=0
WRITE "'(A!B) = ",'(A!B)
'(A!B) = 1
下面的NOT或示例計算一個TRUE和一個FALSE操作數併產生FALSE結果。
SET A=0,B=1
WRITE "A'!B = ",A'!B
A'!B = 0
SET A=0,B=1
WRITE "'(A!B) = ",'(A!B)
'(A!B) = 0
下面的NOT OR(||
)示例計算左操作數,並且因爲它爲TRUE(1)
,所以不計算右操作數。一元值不反轉生成的布爾值,因此表達式返回FALSE(0)
。
SET A=1
WRITE "'(A||B) = ",'(A||B) // Returns 0
'(A||B) = 0