前言
Q语言在执行顺序是从右到左,这与其他编程语言非常的不同,这一点可能会非常的不习惯,再加上本身的是一种vector language,当参数是标量和参数是向量时,常常会有不一样的效果,特别是操作符有各种前缀,中缀,后缀用法,因此要对Q语言的执行顺序非常了解。
一、运算符、函数、动词
Kdb +有名词,动词和副词。所有数据对象和函数都是nouns。Verbs通过减少表达式中的方括号和括号的数量来增强可读性。Adverbs修改二元(2个参数)函数和动词以产生新的相关动词。 副词derived functions称为derived functions或derived verbs。
1. 函数表示方法
Q语言中有着丰富的内置函数,具体可以参考官网介绍:https://code.kx.com/q4m3/A_Built-in_Functions/
当然我们也可以定义自己的函数,我们编写的函数和内置函数之间有两个主要的区别:
1)自定义的函数必须具有字母数字名称,而q内置函数可以是纯符号;
2)自定义的函数只能用于前缀表示法,而q内置函数可以用前缀或中缀。
自定义函数具体形式如下:
F:{[参数1;……;参数n] 表达式1;……;表达式n}
后续会专用一个专栏介绍关于Q语言的自定义函数,此处可以先了解下,本次先着重介绍Q预言的内置函数。
2. 动词和函数表示方法
Q语言中的函数常见的是用前缀或中缀的表示形式,而在大多数编程语言中都习惯采用中缀的形式,如:
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. 原子函数的扩展
参数为原子的我们称为原子函数,原子函数的一个基本特征是它们的动作自动扩展到列表中的项目。
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 /由于长度不相等,因此结果返回长度错误
'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
二、操作符的优先级
在Q语言中,操作符是没有优先级的,这非常重要,与其他编程语言不用,如*或者/的优先级要高于+后者-,而在Q语言中,不存在操作符的优先级,按照顺序从右到左执行,这样做的目的也是为了提高计算或处理速度。
q)2*3+4 /一般编程语言中,结果应该是10,但是在Q中,由于从右到左的执行,而结果就是14
14
q)2*(3+4)
14
q)2*3-4 /一般编程语言中,结果应该是2,但是在Q中,由于从右到左的执行,而结果就是-2
-2
q)2*(3-4)
-2
q)(2+3)*3+4 /一般编程语言中,结果应该是19,但是在Q中,由于从右到左的执行,而结果就是35
35
三、匹配操作符
“~”为匹配操作符,匹配的两个对象必须是一样的类型和一样的值。
q)42~40+2 /由于40+2=42,结果类型为-7h,因此两个相同,结果为真
1b
q)42~42h /由于42h的类型数-5h,42的结果类型为-7h,两个不相同,结果为假
0b
q)42f~42.0
1b
q)42~`42
0b
q)4 2~4 2 /多个值的匹配,每个相同结果才为真,判断整体
1b
q)4 2=4 2 /多个值用=进行匹配,进行单个判断
11b
q)4 2 1=4 2 3 /多个值用=进行匹配,进行单个判断
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) /用=进行匹配结果返回长度不相等的错误
'length
四、等式和其相关操作
前面介绍过匹配,匹配需要两个对象的类型和值是一样结果才是真,关系运算符则不同,关系运算不需要匹配它们的操作数类型,只要他们互相兼容。
1. =和<>
q)42=42i /=号操作符的结果就为真,但是~操作符的结果为假
1b
q)42=42h
1b
q)42=42.0 /=号操作符的结果就为真,但是~操作符的结果为假
1b
q)42=0x42
0b
q)42="*" /=号操作符的结果就为真,但是~操作符的结果为假
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它返回一个布尔结果,并课用于所有数字类型,时间和字符类型,当原数据类型的值为0或者0b时,返回结果为1b;不为零或者1b时返回结果为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 "*" /这里会先将*转换为ASCII的值,然后再判断,由于*好的ASCII值不为0 ,则结果返回0b
0b
q)not " "
0b
q)not "\000"
1b
q)not 2000.01.01 /由于Q的时间是以2000.01.01为原点,因此该值相当于0 ,则结果返回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. 关系运算符:>;<=;>;>=
同样关系运算符也可以用于不同类型的关系判断,其结果返回也是布尔值,对于多个值同时判断,则返回每个对应的判断结果。
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 /由于两边长度不相等,无法进行匹配
'length
q)"zaphod"="Arthur"
000100b
q)"zaphod">"Arthur"
100000b
4. 基本数学运算符:+;-;*;%
与其他编程语言,Q语言也含有基础数学运算符,只是除号由/改为了%,由于/用于注释时使用。
q)2+3 /加运算
5
q)2-3 /减运算
-1
q)2*3 /乘运算
6
q)4%2 /除运算,除运算的结果是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 /布尔类型也可以进行加减乘除运算
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 /不同类型的数据进行数学运算
2436
q)5i*0x2a
210i
q)6+7.0
13f
q)1.0+1b
2f
q)a:4
q)-a /数学基础运算符是二元运算,必须传入两个参数,因此-a不会等于-4,需要用0-a或者neg a进行处理
'-
[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) /整数与列表进行计算
101 201
301 401
五、最大值与最小值操作符
最大值操作符“|”返回最大的结果值,最小值操作符“&”返回最小的结果值,同时也可以用于逻辑与和或的操作。
q)42|43 /返回42与43中的最大值
43
q)98.6&101.9 /返回98.6与101.9中的最小值
98.6
q)0b|1b /返回0b与1b中的最大值(对于二进制也可以理解为或操作)
1b
q)0b&1b /返回0b与1b中的最小值(对于二进制也可以理解为与操作)
0b
q)42|0x2b /返回42与0x2b中的最大值(结果将16进制转换成10进制了)
43
q)0x2a|0x2b
0x2b
q)"a"|"z" /返回“a”与”z”中的最大值(通过ASCII码进行比较)
"z"
q)"a"&"z"
"a"
q)`a|`z /不能对symbol类型进行操作
'type
[0] `a|`z
^
q)2|0 1 2 3 4 /原子与列表进行最大值操作
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的变量的情况下将默认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
七、指数与对数等基本操作
sqrt、exp、log、xexp、xlog为常见的开方、自然常数e、自然对数、幂指数、对数
q)sqrt 2 /根号2
1.414214
q)sqrt 42.4 /根号42.4
6.511528
q)sqrt 1b /对布尔值开根号,变为float类型
1f
q)sqrt 0b
0f
q)sqrt -2 /负数开根号,不会报错,返回值为0n(float类型的空值)
0n
q)sqrt -5
0n
q)exp 1 /以e为底的指数
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 /表示以自然常数e为底的对数
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的对数
5f
q)2 xlog -1
0n
八、更多数学操作符
div和mod分别表示取整和取余,signnum表示数学上的符号函数(符号函数为大于0的值返回结果都为1,小于0的值返回结果都为-1),reciprocal表示求倒数,floor表示向下取整,ceiling表示向上取整,abs表示绝对值。
q)7 div 3 /7除以3,最大只能商2,因此结果返回2
2
q)7 div 2 /7除以2,最大只能商3,因此结果返回3
3
q)6 div 3
2
q)-7 div 3 /对于负数,-7除以3,最大只能商-2,单结果需要向下进1,因此返回结果为-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,返回结果为1
1
q)7 mod 3 /7除以3余1,返回结果为1
1
q)6 mod 3
0
q)-7 mod 2 /-7除以2与7除以-2取余返回结果不同。
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 /符号函数给的参数大于0结果都为1,小于0结果都是-1,参数为0时结果为0
1i
q)signum -9999
-1i
q)signum -1
-1i
q)signum 1
1i
q)signum 0
0i
q)reciprocal 100 /100的倒数
0.01
q)reciprocal 10
0.1
q)reciprocal 1
1f
q)reciprocal -1
-1f
q)reciprocal -10
-0.1
q)reciprocal 0 /数学书0的倒数不存在,Q中则返回无穷大
0w
q)floor 4.6 /对于大于0的数只取整数部分
4
q)floor 4.1
4
q)floor 4
4
q)floor -4.3 /对于小于0的数取整数部分-1
-5
q)ceiling 4.2 /对于大于0的数只取整数部分+1
5
q)ceiling 4.9
5
q)ceiling -4.2 /对于小于0的数只取整数部分
-4
q)ceiling -4.9
-4
q)abs -4 /取绝对值
4
q)abs 1.2
1.2
q)abs -1.2
1.2
九、时间数据操作
前面我们介绍过Q语言中时间的操作非常的强大,日期都是以2000.01.01为时间的起始点,时间都是以00:00:00:0000为起点。由于有了相对的原点,我们就可以将日期和时间转换成整数。
q)`int$1999.12.31 /将1999年12月31日转换成int类型,1999年12月31日与2000年1月1日少一天,因此返回结果为-1
-1i
q)`int$2003.01m /将2003年1月转换成int类型,2003年1月与2000年1月相比多了36个月,因此返回结果为36
36i
q)`int$12:00:00.123 /转换为毫秒
43200123i
q)`int$00:00:00.123 /转换为毫秒
123i
q)2000.01.02=2000.01.02D00:00:00.000000000
1b
q)`timestamp$2001.01.02 /转换为日期+时间的形式
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 /加一天就变为了2015年1月1日
2015.01.01
q)12:00:00+1 /加一分钟
12:00:01
q)12:00:00+01:00:00 /加一个小时
13:00:00
十、别名::
在Q语言中,可以使用::建立别名,别名的好处就是当原数据改变时,别名也变为,但赋值就不会改变
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
网友评论