前言
Q語言在執(zhí)行順序是從右到左,這與其他編程語言非常的不同,這一點可能會非常的不習(xí)慣,再加上本身的是一種vector language,當(dāng)參數(shù)是標(biāo)量和參數(shù)是向量時,常常會有不一樣的效果,特別是操作符有各種前綴,中綴,后綴用法,因此要對Q語言的執(zhí)行順序非常了解。
一、運算符、函數(shù)、動詞
Kdb +有名詞,動詞和副詞。所有數(shù)據(jù)對象和函數(shù)都是nouns。Verbs通過減少表達(dá)式中的方括號和括號的數(shù)量來增強(qiáng)可讀性。Adverbs修改二元(2個參數(shù))函數(shù)和動詞以產(chǎn)生新的相關(guān)動詞。 副詞derived functions稱為derived functions或derived verbs。
1. 函數(shù)表示方法
Q語言中有著豐富的內(nèi)置函數(shù),具體可以參考官網(wǎng)介紹:https://code.kx.com/q4m3/A_Built-in_Functions/
當(dāng)然我們也可以定義自己的函數(shù),我們編寫的函數(shù)和內(nèi)置函數(shù)之間有兩個主要的區(qū)別:
1)自定義的函數(shù)必須具有字母數(shù)字名稱,而q內(nèi)置函數(shù)可以是純符號;
2)自定義的函數(shù)只能用于前綴表示法,而q內(nèi)置函數(shù)可以用前綴或中綴。
自定義函數(shù)具體形式如下:
F:{[參數(shù)1;……;參數(shù)n] 表達(dá)式1;……;表達(dá)式n}
后續(xù)會專用一個專欄介紹關(guān)于Q語言的自定義函數(shù),此處可以先了解下,本次先著重介紹Q預(yù)言的內(nèi)置函數(shù)。
2. 動詞和函數(shù)表示方法
Q語言中的函數(shù)常見的是用前綴或中綴的表示形式,而在大多數(shù)編程語言中都習(xí)慣采用中綴的形式,如:
q)+[2;3] /前綴形式,計算2+3
5
q)2+3 /中綴形式,計算2+3
5
q)=[2;3] /前綴形式,判斷2和3是否相等
0b
q)2=3 /中綴形式,判斷2和3是否相等
0b
3. 原子函數(shù)的擴(kuò)展
參數(shù)為原子的我們稱為原子函數(shù),原子函數(shù)的一個基本特征是它們的動作自動擴(kuò)展到列表中的項目。
q)neg 1 2 3
-1 -2 -3
q)1 2 3+10 20 30
11 22 33
q)1 2 3+10 20 30 40 /由于長度不相等,因此結(jié)果返回長度錯誤
'length
q)neg (1 2 3; 4 5)
-1 -2 -3
-4 -5
q)(1 2 3; 4 5)+(100 200 300; 400 500)
101 202 303
404 505
q)100+1 2 3
101 102 103
q)1 2 3+100
01 102 103
q)100+(1 2 3; 4 5)
101 102 103
104 105
q)(1 2 3; 4 5)+100
101 102 103
104 105
二、操作符的優(yōu)先級
在Q語言中,操作符是沒有優(yōu)先級的,這非常重要,與其他編程語言不用,如*或者/的優(yōu)先級要高于+后者-,而在Q語言中,不存在操作符的優(yōu)先級,按照順序從右到左執(zhí)行,這樣做的目的也是為了提高計算或處理速度。
q)2*3+4 /一般編程語言中,結(jié)果應(yīng)該是10,但是在Q中,由于從右到左的執(zhí)行,而結(jié)果就是14
14
q)2*(3+4)
14
q)2*3-4 /一般編程語言中,結(jié)果應(yīng)該是2,但是在Q中,由于從右到左的執(zhí)行,而結(jié)果就是-2
-2
q)2*(3-4)
-2
q)(2+3)*3+4 /一般編程語言中,結(jié)果應(yīng)該是19,但是在Q中,由于從右到左的執(zhí)行,而結(jié)果就是35
35
三、匹配操作符
“~”為匹配操作符,匹配的兩個對象必須是一樣的類型和一樣的值。
q)42~40+2 /由于40+2=42,結(jié)果類型為-7h,因此兩個相同,結(jié)果為真
1b
q)42~42h /由于42h的類型數(shù)-5h,42的結(jié)果類型為-7h,兩個不相同,結(jié)果為假
0b
q)42f~42.0
1b
q)42~`42
0b
q)4 2~4 2 /多個值的匹配,每個相同結(jié)果才為真,判斷整體
1b
q)4 2=4 2 /多個值用=進(jìn)行匹配,進(jìn)行單個判斷
11b
q)4 2 1=4 2 3 /多個值用=進(jìn)行匹配,進(jìn)行單個判斷
110b
q)(4 2)~(4;2*1)
1b
q)(())~enlist ()
0b
q)(1; 2 3 4)~(1; (2; 3; 4))
1b
q)(1; 2 3 4)=(1; (2; 3; 4))
1b
111b
q)(1 2;3 4)~(1;2 3 4)
0b
q)(1 2;3 4)=(1;2 3 4) /用=進(jìn)行匹配結(jié)果返回長度不相等的錯誤
'length
四、等式和其相關(guān)操作
前面介紹過匹配,匹配需要兩個對象的類型和值是一樣結(jié)果才是真,關(guān)系運算符則不同,關(guān)系運算不需要匹配它們的操作數(shù)類型,只要他們互相兼容。
1. =和<>
q)42=42i /=號操作符的結(jié)果就為真,但是~操作符的結(jié)果為假
1b
q)42=42h
1b
q)42=42.0 /=號操作符的結(jié)果就為真,但是~操作符的結(jié)果為假
1b
q)42=0x42
0b
q)42="*" /=號操作符的結(jié)果就為真,但是~操作符的結(jié)果為假
1b
q)2000.01.01=2000.01.01D00:00:00.000000000 /時間類型的判斷
1b
q)2015.01.01<2015.02m
1b
q)12:00:00=12:00:00.000
1b
q)25<>33 /<>表示不等于
1b
q)25<>25h
0b
q)25<>25.0
0b
q)25<>26.0
1b
2. not
運算符not它返回一個布爾結(jié)果,并課用于所有數(shù)字類型,時間和字符類型,當(dāng)原數(shù)據(jù)類型的值為0或者0b時,返回結(jié)果為1b;不為零或者1b時返回結(jié)果為0b。
q)not 0b
1b
q)not 1b
0b
q)not 42
0b
q)not 0
1b
q)not 0xff
0b
q)not 98.6
0b
q)not "*" /這里會先將*轉(zhuǎn)換為ASCII的值,然后再判斷,由于*好的ASCII值不為0 ,則結(jié)果返回0b
0b
q)not " "
0b
q)not "\000"
1b
q)not 2000.01.01 /由于Q的時間是以2000.01.01為原點,因此該值相當(dāng)于0 ,則結(jié)果返回1b
1b
q)not 2014.01.01
0b
q)not 2000.01.01T00:00:00.000000000
1b
q)not 2000.01m
1b
q)not 12:00:00.000000000
0b
3. 關(guān)系運算符:>;<=;>;>=
同樣關(guān)系運算符也可以用于不同類型的關(guān)系判斷,其結(jié)果返回也是布爾值,對于多個值同時判斷,則返回每個對應(yīng)的判斷結(jié)果。
q)4<42
1b
q)4<42h
1b
q)4h>0x2a
0b
q)-1.414<99i
1b
q)2000.01.01<2000.01.01D00:00:00.000000001
1b
q)2015.01.01<2015.02m
1b
q)"A"<"Z"
1b
q)"A"<"O"
1b
q)`abc<`aba
0b
q)5<=5
1b
q)"A"<="O"
1b
q)"A">="O"
0b
q)5<=5
1b
q)5>=5
1b
q)10 20 30<=30 20 10
110b
q)2=1 2 3 /一個原子可以同時匹配多個原子
010b
q)20 10=10 20 30 /由于兩邊長度不相等,無法進(jìn)行匹配
'length
q)"zaphod"="Arthur"
000100b
q)"zaphod">"Arthur"
100000b
4. 基本數(shù)學(xué)運算符:+;-;*;%
與其他編程語言,Q語言也含有基礎(chǔ)數(shù)學(xué)運算符,只是除號由/改為了%,由于/用于注釋時使用。
q)2+3 /加運算
5
q)2-3 /減運算
-1
q)2*3 /乘運算
6
q)4%2 /除運算,除運算的結(jié)果是float類型
2f
q)a:4
q)b:2
q)a+b
6
q)a-b
2
q)a*b
8
q)a%b
2f
q)1b+1b /布爾類型也可以進(jìn)行加減乘除運算
2i
q)1b-1b
0i
q)42*1b
42
q)1b%1b
1f
q)42%1b
42f
q)1b%42
0.02380952
q)58*0x2a /不同類型的數(shù)據(jù)進(jìn)行數(shù)學(xué)運算
2436
q)5i*0x2a
210i
q)6+7.0
13f
q)1.0+1b
2f
q)a:4
q)-a /數(shù)學(xué)基礎(chǔ)運算符是二元運算,必須傳入兩個參數(shù),因此-a不會等于-4,需要用0-a或者neg a進(jìn)行處理
'-
[0] -a
^
q)0-42
-42
q)0-a
-4
q)neg a
-4
q)1.0 + 10 20 30
11 21 31f
q)10 20 30%1 2 3
10 10 10f
q)100 200 300+1b
101 201 301
q)1+(100 200; 300 400) /整數(shù)與列表進(jìn)行計算
101 201
301 401
五、最大值與最小值操作符
最大值操作符“|”返回最大的結(jié)果值,最小值操作符“&”返回最小的結(jié)果值,同時也可以用于邏輯與和或的操作。
q)42|43 /返回42與43中的最大值
43
q)98.6&101.9 /返回98.6與101.9中的最小值
98.6
q)0b|1b /返回0b與1b中的最大值(對于二進(jìn)制也可以理解為或操作)
1b
q)0b&1b /返回0b與1b中的最小值(對于二進(jìn)制也可以理解為與操作)
0b
q)42|0x2b /返回42與0x2b中的最大值(結(jié)果將16進(jìn)制轉(zhuǎn)換成10進(jìn)制了)
43
q)0x2a|0x2b
0x2b
q)"a"|"z" /返回“a”與”z”中的最大值(通過ASCII碼進(jìn)行比較)
"z"
q)"a"&"z"
"a"
q)`a|`z /不能對symbol類型進(jìn)行操作
'type
[0] `a|`z
^
q)2|0 1 2 3 4 /原子與列表進(jìn)行最大值操作
2 2 2 3 4
q)"zaphod"|"arthur"
"zrthur"
q)1b or 0b /邏輯或操作,也可以理解為返回最大值
1b
q)1b and 0b /邏輯與操作,也可以理解為返回最小值
0b
q)42 or 43 /返回最大值
43
q)42 and 0b /返回最小值,會將0b看成0
0
q)42 or 0b /返回最大值,會講0b看成0
42
六、修飾符:號
在這里:作為一個重載操作符,先介紹其賦值的使用,前面我們看到過比如a:42,意思是將42的值賦值給變量a,與C語言中a=42類似。
q)a:42 /將42的值賦值給變量a
q)a
42
q)a+:1 /給變量a的值加1并賦值給變量a,等價于C語言中的a=a+1
q)a
43
q)a-:1 /給變量a的值減1并賦值給變量a,等價于C語言中的a=a-1
q)a
42
q)a&:21 /比較a的值與21的大小,將小的值賦值給a
q)a
21
q)a|:42 /比較a的值與21的大小,將大的值賦值給a
q)a
42
q)x /由于變量x值未定義,因此直接使用變量x會出錯
'x
[0] x
q)x+:42 /這里定義一個變量x,并將其加42,在之前為定義x的變量的情況下將默認(rèn)x的初始值為0
q)x
42
q)L:100 200 300 400 /定義一個列表L
q)L
100 200 300 400
q)L[1]+:99 /給列表L中的第二個元素+99并賦值給列表中第二個元素
q)L
100 299 300 400
q)L[1 3]-:1 /給列表L中的第二和第四個個元素-1并賦值給列表中第二和第四個元素
q)L
100 298 300 399
q)L1:(1 2 3; 4 5) /定義一個列表L1
q)L1
1 2 3
4 5
q)L1[;1]+:100 /給列表L1的每一行中的第二個元素+100并賦值給列表L1中的每一行中的第二個元素
q)L1
1 102 3
4 105
q)L
100 298 300 399
q)L,:99 / ,號為附加的含義,將99附件到列表L中
q)L
100 298 300 399 99
七、指數(shù)與對數(shù)等基本操作
sqrt、exp、log、xexp、xlog為常見的開方、自然常數(shù)e、自然對數(shù)、冪指數(shù)、對數(shù)
q)sqrt 2 /根號2
1.414214
q)sqrt 42.4 /根號42.4
6.511528
q)sqrt 1b /對布爾值開根號,變?yōu)閒loat類型
1f
q)sqrt 0b
0f
q)sqrt -2 /負(fù)數(shù)開根號,不會報錯,返回值為0n(float類型的空值)
0n
q)sqrt -5
0n
q)exp 1 /以e為底的指數(shù)
2.718282
q)exp 0
1f
q)exp 4.2
66.68633
q)exp -12
6.144212e-006
q)exp -12i
6.144212e-006
q)1e5 /表示1x10的5次方
100000f
q)1e1 /表示1x10的1次方
10f
q)log 1 /表示以自然常數(shù)e為底的對數(shù)
0f
q)log 42
3.73767
q)log 0.001
-6.907755
q)log -1
0n
q)2 xexp 5 /表示2的5次方
32f
q)-2 xexp 5
-32f
q)2 xlog 32 /表示以2為底5的對數(shù)
5f
q)2 xlog -1
0n
八、更多數(shù)學(xué)操作符
div和mod分別表示取整和取余,signnum表示數(shù)學(xué)上的符號函數(shù)(符號函數(shù)為大于0的值返回結(jié)果都為1,小于0的值返回結(jié)果都為-1),reciprocal表示求倒數(shù),floor表示向下取整,ceiling表示向上取整,abs表示絕對值。
q)7 div 3 /7除以3,最大只能商2,因此結(jié)果返回2
2
q)7 div 2 /7除以2,最大只能商3,因此結(jié)果返回3
3
q)6 div 3
2
q)-7 div 3 /對于負(fù)數(shù),-7除以3,最大只能商-2,單結(jié)果需要向下進(jìn)1,因此返回結(jié)果為-3
-3
q)-7 div 2.5
-3
q)7 div -2
-4
q)7 div -3
-3
q)6 div -3
-2
q)7 mod 2 /7除以2余1,返回結(jié)果為1
1
q)7 mod 3 /7除以3余1,返回結(jié)果為1
1
q)6 mod 3
0
q)-7 mod 2 /-7除以2與7除以-2取余返回結(jié)果不同。
1
q)7 mod -2
-1
q)3 4 5 mod 2
1 0 1
q)3 4 5 div 2
1 2 2
q)3 4 5 mod 2 3 4
1 1 1
q)3 4 5 div 2 3 4
1 1 1
q)signum 9999 /符號函數(shù)給的參數(shù)大于0結(jié)果都為1,小于0結(jié)果都是-1,參數(shù)為0時結(jié)果為0
1i
q)signum -9999
-1i
q)signum -1
-1i
q)signum 1
1i
q)signum 0
0i
q)reciprocal 100 /100的倒數(shù)
0.01
q)reciprocal 10
0.1
q)reciprocal 1
1f
q)reciprocal -1
-1f
q)reciprocal -10
-0.1
q)reciprocal 0 /數(shù)學(xué)書0的倒數(shù)不存在,Q中則返回?zé)o窮大
0w
q)floor 4.6 /對于大于0的數(shù)只取整數(shù)部分
4
q)floor 4.1
4
q)floor 4
4
q)floor -4.3 /對于小于0的數(shù)取整數(shù)部分-1
-5
q)ceiling 4.2 /對于大于0的數(shù)只取整數(shù)部分+1
5
q)ceiling 4.9
5
q)ceiling -4.2 /對于小于0的數(shù)只取整數(shù)部分
-4
q)ceiling -4.9
-4
q)abs -4 /取絕對值
4
q)abs 1.2
1.2
q)abs -1.2
1.2
九、時間數(shù)據(jù)操作
前面我們介紹過Q語言中時間的操作非常的強(qiáng)大,日期都是以2000.01.01為時間的起始點,時間都是以00:00:00:0000為起點。由于有了相對的原點,我們就可以將日期和時間轉(zhuǎn)換成整數(shù)。
q)`int$1999.12.31 /將1999年12月31日轉(zhuǎn)換成int類型,1999年12月31日與2000年1月1日少一天,因此返回結(jié)果為-1
-1i
q)`int$2003.01m /將2003年1月轉(zhuǎn)換成int類型,2003年1月與2000年1月相比多了36個月,因此返回結(jié)果為36
36i
q)`int$12:00:00.123 /轉(zhuǎn)換為毫秒
43200123i
q)`int$00:00:00.123 /轉(zhuǎn)換為毫秒
123i
q)2000.01.02=2000.01.02D00:00:00.000000000
1b
q)`timestamp$2001.01.02 /轉(zhuǎn)換為日期+時間的形式
2001.01.02D00:00:00.000000000
q)2000.01.01<2000.01.01D12:00:00.000000000 /判斷大小
1b
q)2000.01.01=0
1b
q)12:00:00=12*60*60
1b
q)1999.12.31<0
1b
q)2014.12.31+1 /加一天就變?yōu)榱?015年1月1日
2015.01.01
q)12:00:00+1 /加一分鐘
12:00:01
q)12:00:00+01:00:00 /加一個小時
13:00:00
十、別名::
在Q語言中,可以使用::建立別名,別名的好處就是當(dāng)原數(shù)據(jù)改變時,別名也變?yōu)?,但賦值就不會改變
q)a:42 /42賦值給a
q)b::a /建立a的別名b
q)c:a /將a的值賦值給c
q)a
42
q)b
42
q)c
42
q)a:43 /修改a的值
q)a
43
q)b /b的值也同時修改
43
q)c /c的值還是42,因此可以看出別名的作用
42