【Lua程序设计】数值

在Lua5.2及之前的版本中所有数值皆为双精度浮点数。Lua5.3开始引入了integer的64位整型。

1. 数值常量

可以使用科学计数法书写数值常量。具有十进制小数或指数的数值会被当做浮点型值,否则会被当做整型值(也就是使用科学计数法写出来的全部为浮点型值)。

浮点型值和整型值皆为number类型。由于类型相同所以是可以相互转换的,同时具有相同算数值的整型值和浮点型值在Lua语言中是相等的(1==1.0为true)。

如果需要知道某一数值的具体类型(float还是int)可以使用math.type(arg)进行获取。

Lua语言还支持0x开头的16进制常量。也可以用于表示小数,由小数部分和以p或P开头的指数部分组成。

print(0x1.a3p+8)--419
print(0xa.b)--10.6875
print(10.6875*4)--42.75
print(0xa.bp2)--42.75

由上可得p开头的指数部分是指乘以2的x次方。
十进制小数转R进制小数,方法为乘R取整,每次乘以相应之后基数后取结果的整数部分。
10.6875----10----a
0.6875*16 = 11.0----11----b
得a.b;

可以使用%a参数,通过string.format对十进制数进行十六进制格式化输出。

2.算数运算

除了常见的加,减,乘,除,取负数等常见的算数运算外还支持取整除法、取模和指数运算。

和其他语言一样Lua中整型与整型进行加,减,乘,取负数,取模,floor除法(//)结果仍然为整型值,如果其一为浮点型值则结果为浮点型值。如果一个为整型值一个为浮点型值在进行运算前会将整型值转换为浮点型值。

除法较为特殊,在Lua中为了避免两个整型值相除和两个浮点型值相除导致不一样的结果,除法运算操作的永远都是浮点数且产生浮点型值的结果。

floor除法使用//运算符,会对得到的商向负无穷取整。
取模运算同其他语言一样,其结果的符号永远与第二个操作数的符号保持一致。
a%b = a - ((a//b)*b)
实数可以使用形如x-x%0.001表示x保留三位小数的结果。

Lua的幂运算和除法一样,操作数永远是浮点型值。

3.关系运算

< > <= >= == ~=
==和~=关系运算符可以用于任意的两个值,当两个值类型不同时,Lua认为他们是不相等的。当类型相同时,如果是数值会忽略其子类型,只对其算数值进行比较。不过相同子类型的比较效率比不同的相对较高。

4.数学库

Lua语言提供标准数学库math。标准数学库由一组标准的数学函数组成,包括三角函数,指数函数,取整函数,最大和最小值函数(max和min),生成随机数的函数(random),常量pi(π)和huge(最大可表示数值)

所有的三角函数都以弧度为单位,并通过deg和rad进行角度和弧度的转换。

4.1随机数发生器

函数math.random用于生成伪随机数。不带参数时返回[0,1)范围的值;带一个整型值n的参数时返回[0,n]范围的值;带两个整型值参数l,u时返回[l,u]范围的值。
函数randomseed用于设置伪随机数发生器的种子。当一个程序启动时,系统固定使用1为种子初始化伪随机数发生器。这样每次运行都会生成相同的伪随机数序列,这样是不好的,所以一般来说会调用math.randomseed(os.time())使用当前系统时间作为种子。

4.2取整函数

math中有三个取整函数:floor、ceil、modf。
floor:向负无穷取整,返回取整后的值
ceil:向正无穷取整,返回取整后的值
modf:向零取整,返回取整后的值及小数部分
当取整结果能够用整数表示时(没超出最大值)返回结果为整数,否则(超出最大值)返回浮点数(其实是科学计数法表示的整数,类型是浮点型)。

5.数值范围

标准Lua使用64位存储整型值,其最大值为2^63-1,
最小值为-2^63。
当在整型操作时出现比最小值小或比最大值大的值时,结果就会回环。在计算机领域回环的意思是丢弃最高进位。
假设最高位存在,那么在Lua中应该是第65个比特位,表示2^64。

对于双精度浮点数,Lua使用64个比特位表示所有数值,其中11位为指数。
双精度的精度是有限的,所以很多超出精度范围的数,可能其值与真实数值不同。对于无限循环的小数,也会有一个小数位数限制而得到预想外的值,1/n*n得到的值不一定等于1,而是会非常接近1的一个小数。对于有限小数在用二进制表示时也可能是无限小数,导致得到的结果与预期不同。
关于浮点数的位存储说明:
这个文章写的比较详细可以看看

我们可以简单的通过增加0.0的方式将整型值强制转换为浮点型值。对于绝对值小于2^53次方的所有整型值的表示与双精度浮点型值的表示一样,对于超出该值的整型值而言,强制转换为浮点型值时可能导致精度损失。

通过与0进行按位或运算(|),可以把浮点型值强制转换为整型值。但是要注意如果该数值的表示与整型值表示不完全一致(存在小数部分)那么会转换失败,抛出异常。
另一种转换方式为使用math.tointeger(),该函数在无法转换为整型时返回nil。

6.运算符优先级

^
 一元运算符:-(去反),#(取table长度),~,not(非)
 *(乘),/(除),//(floor除法),%(取模(取余))
 +,-
 . .(两个连续的点,连接字符串)
 <<(位左移),>>(位右移)
 &(按位与)
 ~(按位异或)
 |(按位或)
 <,>,<=,>=,~=,==
 and
 or


在二元运算符中除了幂运算符和连接操作符是右结合的外,其他运算符都是做结合的。