跳到主要内容

争取两三周入门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)。

三角函数

以弧度为单位,通过函数degrad进行角度和弧度的转换:

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位)中,最大为26312^{63}-1​。超过最大值会发生整型溢出,即发生回环。

math.maxinteger + 2	 --> -9223372036854775807

对于浮点数而言,在标准Lua中,64位双精度浮点数可以表示范围从10308-10^{308}1030810^{308}的数;精简Lua中,32位单精度浮点数,可以表示范围从1038-10^{38}103810^{38}​的数。如果浮点数发生溢出,结果会被取近似。

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