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