概述
所有的数据都是通过最小单位 atom 构造。q 语言中大部分数据类型与传统语言类似,但是多出了 date 和 time 相关的类型,用来加速时间序列运算。下表给出了 q 语言和几个传统语言数据类型的对比:
下表给出了 Q 语言各个类型的详细信息:
1. 整型数据
long: 8 字节;42, 42j
short: 2 字节有符号数;其后必须带后缀 h; eg: -123h
int: 4 字节有符号数;其后必须带后缀 i; eg: 1234567890i
2. 浮点数据
支持单精度和双精度浮点数据类型。
float: 8 字节;后缀 f; 传统语言中的 double; eg: 3.1415926, 1f, 1.0, 1.234e07, 1.234e-7
real: 4 字节;后缀 e; 传统语言中的 float; eg: 12.34e, 1.234e7e 注:不建议使用 real 这个类型,因为在许多金融问题中,real 的精度往往不够用
浮点数显示精度: q console 默认显示 7 位小数,可以通过命令 \P 来最多显示 16 位小数,也可以通过 \P 0 来显示完整的 17 位小数,但是最后一位小数不可信。
q)f12:1.23456789012
q)f16:1.234567890123456
q)\P 12
q)f12
1.23456789012
q)f16
1.23456789012
q)\P 16
q)f12
1.23456789012
q)f16
1.234567890123456
q)\P 0
q)1%3
0.33333333333333331
3. Binary 数据
boolean : 1 字节;后缀 b;没有 true 或者 false 关键字,1b 代表 true, 0b 代表 false
byte : 使用 1 字节保存 8 位数据,前缀 0x 紧跟着 2 个 16 进制数,大小写均可。eg: 0x2A, 0x2a
GUID : globally unique identifier. 在时间和空间上都唯一,可以对 null guid 值 0Ng 使用? 来生成一个 guids 的列表。eg: 1?0Ng, 2?0Ng, -2?0Ng 使用正号和负号生成 guid 列表的区别在于:正号使用同一个随机种子(seed), 而负号使用的种子是随机的可以通过解析一个 16 进制数字来构造 guid:”G”$”61f35174-90bc-a48a-d88f-e15e4a377ec8″,同样,可以使用命令 sv 来从一个 16 个 byte 的列表构造 guid: 0x0 sv 16?0xff。
GUID 适用的运算符仅有:~, =, <, >, null
4. Text 数据
q 中共有两种 text 类型数据,更类似于 SQL 中的 CHAR 和 VARCHAR。
char : 1 字节;对应 SQL 中的 CHAR;用双引号表示;特殊字符用 \ 作为前缀来显示,尽管在 q -console 中依旧将 \ 显示了出来,但是实际上它就是一个单字符
q)”\”” / double-quote
“\””
q)”\\” / back-slash
“\\”
q)”\n” / newline
“\n”
q)”\r” / return
“\r”
q)”\t” / horizontal tab
“\t”
q)”\142″
“b”
symbol : 前缀 ` eg: q, `zaphod`symbol 与 char 一样,同样是原子数据,这意味着 symbol 不可拆分,symbol 中的单个字符不可获取。symbol 不是 string, 并且 symbol 数据 `a 与 char 数据 ”a” 不相等。
5. 时间类型数据
date : 4 字节,表示为 yyyy.mm.dd; 其表示值为从 2000.01.01 开始的日期数,在之前的为负值,之后的为正值。
q)2000.01.01=0
1b
表示的累积日数可以通过强制转换得到:
q)`int$2000.02.01
Time :
如果毫秒级够用的话,使用 time 类型,表示为 hh:mm:ss.uuu;其表示值为从 00:00 的毫秒 (milliseconds) 数
q)12:34:56.789
12:34:56.789
q)12:00:00.000=12*60*60*1000
1b
其表示值同样可以通过强制转换来获取
如果毫秒级不够用的话,使用 timespan 类型;其表示为从 00:00 开始的纳秒 (nanoseconds) 数, 表示为 0Dhh:mm:ss.nnnnnnnnn。其中 0D 是可选的。
q)12:34:56.123456789
0D12:34:56.123456789
q)12:34:56.123456 / microseconds become nanos
0D12:34:56.123456000
Date-Time : (已弃用的) 使用 T 进行分隔:
q)2000.01.01T12:00:00.000
_
q)2000.01.02T12:00:00.000=1.5
1b
可以通过 q)date$2000.01.02T12:00:00.000` 来提取日期和时间
更推荐使用的类型是 timestamp, 是 date 类型和 timespan 类型的连接,通过 D 进行分离。其表示值为从千禧年计数的纳秒数,之前为负数,之后为正数。同样,有如下的操作:
q)2014.11.22D17:43:40.123456789
q)`long$2014.11.22D17:43:40.123456789
q)`date$2014.11.22D17:43:40.123456789
q)`timespan$2014.11.22D17:43:40.123456789
month : 32 位带符号整型,表示为 yyyy.mm 和一个尾符号 m, 其表示值为从千禧年计数的月份数。注意不要忘记带尾缀 m。
q)2015.11m
q)2001.01m=12
1b
minute : 32 位带符号整型,表示为 hh:mm, 其表示值为从 00:00 计数的分钟数。
q)12:30
q)12:00=12*60
1b
second : 32 位带符号整型,表示为 hh:mm:ss, 其表示值为从 00:00 计数的秒数。
q)23:59:59
q)23:59:59=-1+24*60*60
1b
构成和点操作符 : 可以通过点操作符提取日期,月份,日等
q)dt:2014.01.01
q)dt.year
2014i
q)dt.mm
q)dt.dd
q)ti:12:34:56.789
q)ti.hh
12i
q)ti.mm
q)ti.ss
但是更推荐使用强制转换符,因为它对所有有意义的时间提取和转换都是有效的:
q)`dd$dt
1i
q)`mm$dt
q)`dd$dt
q)`month$dt
2014.01m
6. 算术 Infinities 和 Nulls
一些特殊含义的表示:
Literal Value
0w Positive float infinity
-0w Negative float infinity
0n Null float ; NaN, or not a number
0W Positive long infinity
-0W Negative long infinity
0N Null long
注意小写的 w 代表 float, 大写的 W 代表整数。
在 q 语言中,数字的除法结果总是 float. 正数除以 0 的结果为正无穷,负数除以 0 的结果为负无穷。在数学中,0 除以 0 是未定义的,因此,0n 代表 NaN。整型无穷可以参与比较并返回正确的结果
q)42<0W
1b
q)-0W<42
1b
无穷代表实际的值:
q C Equivalent Numeric
0N MIN_INT -9223372036854775808
-0W MIN_INT+1 -9223372036854775807
0W MAX_INT +9223372036854775807
因此,整型的大小顺序为:
0N < -0W < normal integer < 0W
q)9223372036854775806+1
0W
q)-0W-1
0N
q)-0W+1
-9223372036854775806
实际上 q 语言没有溢出解释了如下现象:
q)0W+1
0N
q)0W+2
-0W
q)0W+3
-9223372036854775806
7. Nulls
null 值一般表示的是缺失数据。在 q 中,null 与正常的值占用同样的空间,如下总结了 null 的不同类型值:
type null
boolean 0b
guid 0Ng (00000000-0000-0000-0000-000000000000)
byte 0x00
short 0Nh
Int 0N
long 0Nj
real 0Ne
float 0n
char ” ”
sym `
timestamp 0Np
month 0Nm
date 0Nd
datetime 0Nz
timespan 0Nn
minute 0Nu
second 0Nv
time 0Nt
注意:”” 不是一个 null char, 而是一个 char 的空列表
使用 null 指令而不是 = 来测试一个值是不是 null 值,因为 q 语言是动态类型的,而 null 指令是类型独立的。
q)null 42
0b
q)null `
1b
q)null ” ”
1b
q)null “”