代码先锋网 代码片段及技术文章聚合

lua number类型详解(转载)

技术标签: Lua学习笔记  lua

lua number类型详解和math.floor存在误差的问题

一、Lua number数据类型

  • lua的number类型,是默认当成双精度浮点类型来运算的。也就是说number会底层当做double类型来处理,精度是16~17位
  • 在Lua 5.2及之前的版本中,所有的数值双精度类型的实浮点数格式表示
  • 从Lua 5.3版本开始,Lua语言为数值格式提供了两种选择:
    • 整型值:称为interger的64位整型
    • 浮点型值:称为float的双精度浮点类型

二、类型判断

type()函数

  • 使用type()函数可以获取整型值和浮点型值的类型,返回的都是number(表示数值类型)

    print(type(3)) 			--number
     
    print(type(3.5))		--number
     
    print(type(3.14e3))		--number
    

math.type()函数

  • **如果想要区分整型值和浮点型值,**可以使用这个函数

    print(math.type(3))		--integer
     
    print(math.type(3.5))	--float
     
    print(math.type(3.14e3)) --float
    

三、十六进制表示

  • Lua也支持以0x开头的十六进制常量
  • Lua不仅支持十六进制的整型、还支持十六进制的浮点数
print(0xff)				--255

print(0x1A3)			--419

print(0x0.2)			--0.125
  • 十六进制浮点数还可以由小数部分和以p或P开头的指数部分组成**。
  • 通过string.format()的%a参数可以对上面的这种格式进行格式化的输出
  • 虽然这种格式很难阅读,但是****这种格式可以保留所有浮点数的精度,并且比十进制的转换速度更快****
print(0x1p-1)						--0.5

print(string.format("%a", 419)) 	  --0x1.a3p+8
 
print(string.format("%a", 0.5))		  --0x1p-1

四、算术运算

  • Lua支持的算术运算有:

    • 加(+)、减(-)、乘(*)、除(/)
    • 取负数(-)
    • 取整除法/floor除法(//)
    • 取模(%)
    • 指数运算
    • 幂运算(^)
  • Lua 5.3引入整型的主要建议是:开发人员要么选择忽略整型和浮点型二者之间的不同,要么就完整地控制每一个数值的表示。因此,****所有的算术操作符不论操作整型值还是浮点型值,结果都是一样的****

  • 整型值和浮点型值之间的算术运算

    • 如果两个操作数都是整型值,则结果也是整型值;否则就是浮点型值

    • 当两个操作数的类型不同时,****运算之前会先将整型值转换为浮点型值****

    • 除法的注意事项

      • 由于两个整数相处并不一定是整数,因此****当两个数进行相除时,interger都会转换为浮点数****(即使两个操作数都是整数液转换)
      • 并且除法运算的结果也是浮点数
    • floor除法

      • floor除法****会对得到的商向负无穷取整,从而保证结果是一个整数****
      • **这样,floor除法就可以与其他算术运算一样遵循同样的规则:**如果操作数都是整型值,那么结果就是整型值,否则就是浮点数类型
      print(3 // 2)		-- 1
       
      print(3.0 // 2)		-- 1.0
       
      print(6 // 2)		-- 3
       
      print(6.0 // 2.0)	-- 3.0
       
      print(-9 // 2)		-- -5
       
      print(1.5 // 0.5)	-- 3.0
      

      取负数运算

      • 返回一个值的负数
      • 使用的时候注意,对要操作的表达式的结果要加上括号,否则有点像是定义一个负数的感觉

      取模运算

      • 取模运算的结果类型与上面介绍的一样,如果两个操作数都是整型值则返回整型;否则返回浮点数
      • 对于实数类型(浮点数)而言,取模运算有一些不同,例如x-x%0.01恰好是x保留2位小数的结果,x-x%0.001恰好是x保留3位小数的结果
      local x = math.pi
       
      print(x - x%0.01)		-- 3.14
       
      print(x - x%0.001)		-- 3.141
      
      • **演示案例:**我们可以使用取模运算检查某辆车在拐过指定的角度后是否能够原路返回。假设使用度作为角度的单位,那么我们可以使用下面的函数
      -- 角度
      local tolerance = 10 
      function isturnback1(angle)
          angle = angle % 360
          return (math.abs(angle - 180) < tolerance)
      end
      print(isturnback1(-180))		-- true
      print(isturnback1(90))			-- false
      
      -- 弧度
      local tolerance = 0.17
      function isturnback2(angle)
          -- 这一条语句实现了将任意范围的角度归一化到[0,2π)之间
          angle = angle % (2*math.pi)
          return (math.abs(angle - math.pi) < tolerance)
      end
      print(isturnback2(-180))		-- false
      print(isturnback2(90))			-- false
      

      幂运算

      • Lua也支持幂运算,使用符号^表示
      • 像除法一样,****幂运算的操作数和结果也永远是浮点类型****(整型类型在幂运算时不能整除)
      • 我们可以****使用x0.5来计算x的平方根,使用x(1/3)来计算x的立方根****

五、关系运算

  • Lua支持的关系运算符如下:
    • 大于(>)、小于(<)
    • 大于等于(>=)、小于等于(<=)
    • 相等(==)
    • 不相等(~=)
  • Lua关系运算的结果都是boolean类型
  • **==、~=说明:**这两个运算符可以应用于任意两个值,当这两个值的类型不同时,Lua语言认为它们是不相等的;否则,会根据它们的类型再对两者进行比较
  • ****比较数值时永远忽略数值的子类型,****数值究竟是以整型还是浮点型表示并无区别,只与算术值有关(尽管如此,比较具有相同子类型的数值时效率更高)
print(1.0 == 1)			-- true
 
print(1 == 1)			-- true
 
print(1.1 == 1)			-- false

六、数学库

  • Lua语言提供了标准数学库math,由一组标准的数学函数组成,包括:

    • 三角函数(sin、cos、tan、asin等):所有三角函数都以弧度为单位,并通过函数deg和rad进行角度和弧度的转换
    • 指数函数
    • 取整函数
    • 最大函数max、最小函数min
    • 用于生成伪随机的伪随机函数(random)
    • 常量pi
    • 常量huge(最大可表示数值,大多大叔平台上代表inf)

    随机数发生器

    • 函数math.random()用于生成伪随机数,一共有三种调用方式
      • 不带参数调用时:函数返回一个在[0,1)范围内的均匀分布的伪随机实数
      • 当使用带有一个整型值n的参数调用时:函数返回一个在[1, n]范围内的伪随机整数
      • 使用两个整型值l和u的参数调用时:函数返回在[l, u]范围内的伪随机整数换
    print(math.random())			-- 0.001251220703125
     
    -- 可以模拟掷骰子的结果
    print(math.random(6))			-- 4
     
    print(math.random(10, 50))		-- 17
    
    • 函数randomseed()用于设置伪随机数发生器的种子,该函数的唯一参数就是数值类型的种子
      • 在一个程序启动时,系统固定使用1为种子初始化伪随机发生器;如果不设置其他的种子,那么每次程序运行时都会生成相同的伪随机数序列
      • 从调试的角度看,这是一个不错的特性,然而,对于一个游戏来说却会导致相同的场景重复不断的出现。为了解决这个问题,**通常调用math.randomseed(os.time())**来使用当前系统时间作为种子初始化随机数发生器(os.time()在后面文章介绍)

    取整函数

    • 数学库提供了三个取整函数:
      • floor:向负无穷取整
      • ceil:向正无穷取整
      • modf:向零取整
    • 当取整的结果能用整数表示时,返回结果为整型值,否则返回浮点型值
    • modf除了返回取整后的值之外,还会返回小数部分作为第二个结果(Lua支持一个函数返回多个值)
    • 如果参数本身是一个整型值,那么它将原样返回
    • 如果想将数值x向最近的整数取整,可以对x+0.5调用floor函数

七、数值类型取值范围

整型取值范围

  • 标准Lua使用64个比特位来存储整型值,其最大值为263-1,约等于109
  • 数学库中的math.maxinteger和math.mininteger常量分别定义了整型值的最大值和最小值
print(math.maxinteger)			-- 9223372036854775807
 
print(math.mininteger)			-- -9223372036854775808
  • **回环:当数值很大或者很小发生溢出时,就会发生回环。回环的意思就是结果只能在maxinteger和mininteger之间,也就是对2^64取模的算术结果。
print(math.maxinteger + 1 == math.mininteger)		-- true
 
print(math.mininteger - 1 == math.maxinteger)		-- true
 
print(-math.mininteger == math.mininteger)			-- true
 
print(math.mininteger // -1 == math.mininteger)		-- true

浮点类型取值范围

  • 对于浮点数而言,标准Lua使用双精度。标准Lua使用64个比特位表示所有数值,其中11位为指数。双精度浮点数可以表示具有大致16个有效十进制位的数,范围从 -10^308 ~ 10^308
  • 双精度浮点数对于大多数实际应用而言是足够大的,但是我们必须了解精度的限制。如果我们使用十位表示一个数,那么1/7会被取整到0.142857142。如果我们使用十位计算1/7*7,结果会是0.999999994而不是1。此外,用十进制表示的有限小数在用二进制表示时可能是无限小数。例如,12.7-20+7.3即便使用双精度表示也不是0,这是由于12.7和7.3的二进制表示不是有限小数
print(12.7-20+7.3)		-- -8.8817841970013e-016
  • 由于整型值和浮点型值的表示范围不同,****因此当超过它们的表示范围时,整型值和浮点型值的算术运算会产生不同的结果:****
print(math.maxinteger + 2)		-- -9223372036854775807
 
print(math.maxinteger + 2.0)	-- 9.2233720368548e+018
  • 上面的结果分析:
    • 第一行对最大可表示整数进行了整型求和,结果发生了回环
    • 第二行对最大可表示整数进行了浮点型求和,结果被取整成了一个近似值。

八、整型值与浮点型值之间的转换

整数转浮点数

  • 我们可以通过将整型值加上0.0将其转换为浮点型:

  • 小于2^53(即9007199254740992)的所有整型值的表示与双精度浮点型值的表示一样,对于绝对值超过了这个值的整型值而言,在将其强制转换为浮点型值时可能导致精度损失

    print(-3 + 0.0)						-- -3.0
     
    print(9007199254740991 + 0.0 == 9007199254740991)	--true
     
    print(9007199254740992 + 0.0 == 9007199254740992)	--true
     
     
    -- 9007199254740992 + 1被取整为9007199254740992,因此不相等
    print(9007199254740993 + 0.0 == 9007199254740993)	--false
    

浮点数转整数

  • **通过与0进行按位或运算,**可以把浮点型值转换为整型值
  • 在将浮点数强制转换为整数时,Lua会检查数值是否与整型值表示完全一致(即没有小数部分且其值在整型值的表示范围内)。如果****不满足条件则会抛出异常****
print(3.0)		--3.0
 
print(3.0 | 0)	-- 3

print(3.0 | 0)	-- 报错
  • 对小数取整必须显式地调用取整函数
  • 另一种把浮点数转换为整型值的方式是使用math.tointeger(),该函数会在输入参数*无法转换为整型值时返回nil***:
print(math.tointeger(-258.0))		-- -258
 
print(math.tointeger(2^30))			-- 1073741824
 
-- 不是整数值
print(math.tointeger(5.01))			-- nil
 
-- 超出范围
print(math.tointeger(2^64))			-- nil

原文链接:https://blog.csdn.net/qq_41453285/article/details/107933437

版权声明:本文为weixin_43284350原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_43284350/article/details/118309029

智能推荐

Lua闭包详解

文章目录 函数是第一类值 非全局函数 词法定界 小试函数式编程     在Lua语言中,函数是严格遵循词法定界的第一类值。     “第一类值”以为这Lua语言中的函数与其他常见类型的值具有同等权限:一个程序可以将某个函数保存到变量中或表中,也可以将某个函数作为参数传递给其他函数,还可以将某个函...

lua function 详解

lua function lua八种数据类型 nil 全局变量没被赋值默认为 nil,删除变量就赋值为 nil boolean(bool) false和nil为假,其它都为真 number 实数,可以是整数,浮点数 string 字符串,一旦赋值不能被修改,可以通过方法string.gsub()来修改 function 函数 table 数组、容器 userdata (类,其它语言转换过来就变成u...

Lua语言详解

Lua是一个小巧的脚本语言。它是巴西里约热内卢天主教大学(Pontifical Catholic University of Rio de Janeiro)里的一个由Roberto Ierusalimschy、Waldemar Celes 和 Luiz Henrique de Figueiredo三人所组成的研究小组于1993年开发的。 其设计目的是为了通过灵活嵌入应用程序中从而为应用程序提供灵活...

Lua EmmyLua 注解详解

Lua EmmyLua 注解详解 Why 为了使 IDE 编码体验和强语言相近 让 IDE 提前发现编码错误 BUG 查找更方便 代码阅读更方便 建议 明确字段类型 明确字段访问修饰符 明确方法参数类型 善用 “:” 继承 “|” 或 ","多个 支持格式 –类 —@class MY_TYPE[:PAREN...

Redis与Lua详解

Lua Lua语法 Lua 数据类型 Lua 是动态类型语言,变量不要类型定义,只需要为变量赋值。 值可以存储在变量中,作为参数传递或结果返回。 Lua 中有 8 个基本类型分别为:nil、boolean、number、string、userdata、function、thread 和 table。 数据类型 描述 nil 这个最简单,只有值nil属于该类,表示一个无效值(在条件表达式中相当于fa...

猜你喜欢

Lua 脚本详解

Lua是redis 2.6 版本最大的亮点,通过内嵌对Lua 环境的支持,Redis 解决了长久以来不能高效地处理CAS (check-and-set)命令的缺点,并且可以通过组合使用多个命令,轻松实现以前很难实现或者不能高效实现的模式。...

Lua调试:getinfo详解

Lua调试:getinfo详解   getinfo是调试Lua程序时一个很重要很常见的函数,主要用于获取函数调用的基本信息。这个函数的难点在于各个参数的含义。下面一一介绍。 一、函数简介: 1.原型:getinfo(level, arg) 2.调用:debug.getinfo(level, arg) 3.返回值:返回一个包含函数信息的table,table的内容由参数arg决定,包含哪个函数的信息...

lua值与类型

Lua 中有八种基本类型: nil, boolean, number, string, function, userdata, thread, and table. Nil 类型只有一种值 nil ,它的主要用途用于标表识和别的任何值的差异 Boolean 类型只有两种值:false 和 true。 nil 和 false 都能导致条件为假 userdata 类型用来将任意 C 数据保存在 Lua...

Lua -- 类型和值

注:lua5.0以上版本去除了table.getn方法,可以用#tableName代替 Lua是动态类型语言,变量不要类型定义。Lua中有8个基本类型,分别为:nil、boolean、number、string、userdata、function、thread和table。函数type可以测试给定变量或者值的类型。 变量没有预定义的类型,每一个变量都可能包含任一种类型的值。 注意上面最后两行,我们...

Lua 数据类型

Lua 数据类型 作者:杨梦鸽 校对:翟舒青 Lua是动态类型语言,变量不要类型定义,只需要为变量赋值。 值可以存储在变量中,作为参数传递或结果返回。 Lua中有8个基本类型分别为:nil、boolean、number、string、userdata、function、thread和table。 数据类型 描述 nil 这个最简单,只有值nil属于该类,表示一个无效值(在条件表达式中相当于fals...