02 - 数值类型
争取两三周入门 Lua!
在 Lua5.3 以前,所有数值都以双精度浮点格式表示。从 Lua5.3 开始,Lua 为数值格式(number)提供了两种选择:
- 64 位整型
integer
; - 双精度浮点型
float
;
如果资源受限,可将 Lua 编译为精简 Lua(Small Lua)模式,该模式使用 32 位整型和单精度浮点型。
数值常量
可用科学计数法书写数值常量:
4.57e-3 --> 0.00457
具有十进制小数或者指数的数值会被当做浮点型值,否则会被当做整型值。
由于整型值和浮点型值的类型都是 数值 (number),它们是可以相互转换的:
type(-3) --> number type(-3.0) --> number -3 == -3.0 --> true
如果要区分数值是整型还是浮点型,可用 math.type()
:
math.type(3) --> integer math.type(3.0) --> float
Lua 也支持以 0x 开头的十六进制常量,还支持十六进制的浮点数,这种十六进制浮点数由小数部分和以 p/P 开头的指数部分组成:
0xff --> 255 0x0.2 --> 0.125 0xa.bp2 --> 42.75
可用 string.format()
的 %a
参数格式化输出十六进制小数:
string.format("%a", 419) --> 0x1.a3p+8
虽然这种格式很难阅读,但可保留浮点数精度且比十进制转换速度更快。
运算符
算数运算
加减法:
13 + 15 --> 28 13.0 + 15.0 --> 28.0 13 + 15.0 --> 28.0
乘法:
-(3 * 6.0) --> -18.0
除法:
3.0 / 2.0 --> 1.5 3 / 2 --> 1.5
如果想要整数除法,需要用 //
,它会将结果向下取整:
3 // 2 --> 1 3.0 // 2 --> 1.0 -9 // 2 --> -5
取模:
-- 模运算定义: a % b == ((a // b) * b) 5 % 2 --> 1 -- 实数模运算: 获得模数后面位数的实数 x = math.pi x % 0.01 --> 0.0015926535897931 x - x % 0.01 --> 3.14
幂运算:
4^0.5 --> 2.0
关系运算
Lua 提供下列关系运算:
< > <= >= == ~=
这些关系运算的结果都是 Boolean
类型,~=
是不等号。
运算符优先级
Lua 的运算符优先级如下(从高到低):
^ 一元运算符(- # ~ not) * / // % + - .. (连接) << >> (按位移位) & (按位与) ~ (按位异或) | (按位或) < > <= >= ~= == and or
数学库
Lua 提供了标准数学库 math
。由一组标准的数学函数组成,包括三角函数 (sin, cos, tan, asin 等),指数函数,取整函数,最大最小函数,生成伪随机数的函数等;并且有常量 pi 和 huge(最大表示数值,在大多数平台上为 inf)。
三角函数
以弧度为单位,通过函数 deg
和 rad
进行角度和弧度的转换:
math.sin(math.rad(30)) --> 0.5 math.deg(math.asin(0.5)) --> 30.0
随机数发生器
函数 math.random
用于生成伪随机数,有三种调用方式:
- 不带参数调用:返回一个在 [0,1) 范围内均匀分布的伪随机实数。
- 带整型 n 的调用:返回一个在 [1,n] 范围内的伪随机整数。
- 带整型 l 和 u 的调用:返回在 [l,u] 范围内的伪随机整数。
函数 math.randomseed
用于设置伪随机数发生器的种子,该函数的唯一参数就是数值类型的种子。在程序启动时,随机数发生器的种子固定为 1,为了解决这个问题,通常用 math.randomseed(os.time())
来设置种子。
取整函数
数学库提供了 3 个取整函数:
- 向负无穷取整
floor
; - 向正无穷取整
ceil
; - 向 0 取整
modf
;
当取整结果能够用整型表示时,返回结果为整型,否则返回浮点型。除了返回取整后的值外,modf
还会返回小数部分作为第二个结果。
如果要让数值 x 向最近整数取整,可这样写:
function round(x) local f = math.floor(x) if (x == f) or (x % 2.0 == 0.5) then return f else return math.floor(x + 0.6) end end round(2.5) --> 2 round(3.5) --> 4 round(-1.5) --> -2
数值范围
数学库中的常量定义了整型值的最大值 math.maxinteger
和最小值 math.mininteger
。在标准 Lua(64 位)中,最大为
math.maxinteger + 2 --> -9223372036854775807
对于浮点数而言,在标准 Lua 中,64 位双精度浮点数可以表示范围从
math.maxinteger + 2.0 == math.maxinteger + 1.0 --> true
整型与浮点型转换
整型 -> 浮点型
可以将在范围内的整型转换为浮点型:
-3 + 0.0 --> -3.0
浮点型 -> 整型
浮点型可通过位运算方式强制转换为整型:
2^53 | 0 --> 9007199254740992
如果浮点数有小数部分或不在整型范围内,会抛出异常:
3.2 | 0 stdin:1: number has no integer representation
除此之外,还能用 math.tointeger
将数值类型强制转换为整型,无法转换时返回 nil
:
math.tointeger(-258.0) --> -258 math.tointeger(5.01) --> nil
这个函数在需要检查一个数字能否被转换成整型值时尤为有用。例如,以下函数在可能时会将输入参数转换为整型值,否则保持原来的值不变:
function cond2int(x) return math.tointeger(x) or x end