当前位置: 首页 > news >正文

Lua中使用math.floor产生bug的问题

引子

local testNum1 = 38.48
print("testNum1 = ", testNum1)

local testNum2 = testNum1 * 100
print("testNum2 = ", testNum2)

local testNum3 = math.floor(testNum2)
print("testNum3 = ", testNum3)

--[[
testNum1 = 	38.48
testNum2 = 	3848
testNum3 = 	3847  -- 问题出现
]]

test

local testNum, addNum = 0.01, 0.01
for i = 1, 10000 do
    if testNum * 100 ~= math.floor(testNum * 100) then
        print(i, testNum * 100, math.floor(testNum * 100))
    end
    testNum = testNum + addNum
end

--[[
...
2343	2343.0000000001	2343
2344	2344.0000000001	2344
2345	2345.0000000001	2345
2346	2346.0000000001	2346
...
5563	5562.9999999997	5562
5564	5563.9999999997	5563
5565	5564.9999999997	5564
5566	5565.9999999997	5565
5567	5566.9999999997	5566
...
]]

溯源

由于Lua中的Number类型实际上是double(双精度浮点型),在为小数的时候应该特别注意:两个小数相等,不能用等号,而应该用它们的差的绝对值小于一个很小的数(比如math.abs(a - b) < 10e-6)!在程序中如何判断两个浮点数相等

因为电脑是用二进制存储数据的,而类似0.1这样的数字在电脑里存储起来其实是一个很长的数字,在二进制里0.1可能是一个无限不循环小数,所以我们会在一定程度上截取下来,截取之后就难免导致了实际值和我们存储的值有很小很小的差异!

这就导致了5562.9999999997和5563在我们看来是相等的两个数,在进行math.floor之后就出现了偏差,因为math.floor(5562.9999999997)会向下取整从而等于5562!

同理,math.ceil也会有同样的问题!

所以在Lua中使用math.floor和math.ceil的时候需要留意一下这个问题!

相关文章:

  • 一个速度不错的PSP电影批量转AVC的软件
  • PSP用MP4影片最简单的转换技巧分享
  • cocos2d-lua:节点坐标系和世界坐标系之间的的转换
  • 制作高清晰全屏影视PMPAVC的方法
  • VS Code常用快捷键整理
  • cocos2d-lua:将打印的Lua日志写入本地文件
  • devhook 0.46 psp1.5 模拟2.71
  • Lua错误处理之error、assert、pcall和xpcall
  • PSP完美显示中文歌曲名的方法
  • Lua之元表和元方法
  • 30分钟搞定BASH脚本编程[zz]
  • Lua之面向对象的实现
  • 不同种类的webservice错误信息
  • Lua中的require与package.loaded
  • 配置文件多个一个符号,导致struts抛出了匪夷所思的错误
  • 【node学习】协程
  • 3.7、@ResponseBody 和 @RestController
  • C++入门教程(10):for 语句
  • echarts花样作死的坑
  • JavaScript类型识别
  • java取消线程实例
  • mysql 数据库四种事务隔离级别
  • Spring核心 Bean的高级装配
  • Yeoman_Bower_Grunt
  • 从零到一:用Phaser.js写意地开发小游戏(Chapter 3 - 加载游戏资源)
  • 从零开始的webpack生活-0x009:FilesLoader装载文件
  • 第2章 网络文档
  • 基于OpenResty的Lua Web框架lor0.0.2预览版发布
  • 猫头鹰的深夜翻译:Java 2D Graphics, 简单的仿射变换
  • 浅谈JavaScript的面向对象和它的封装、继承、多态
  • 数据科学 第 3 章 11 字符串处理
  • 一个项目push到多个远程Git仓库
  • 应用生命周期终极 DevOps 工具包
  • 在Docker Swarm上部署Apache Storm:第1部分
  • HanLP分词命名实体提取详解
  • ​LeetCode解法汇总2182. 构造限制重复的字符串
  • ​LeetCode解法汇总2304. 网格中的最小路径代价
  • ​软考-高级-系统架构设计师教程(清华第2版)【第12章 信息系统架构设计理论与实践(P420~465)-思维导图】​
  • ​总结MySQL 的一些知识点:MySQL 选择数据库​
  • $.ajax()参数及用法
  • (zt)最盛行的警世狂言(爆笑)
  • (超简单)使用vuepress搭建自己的博客并部署到github pages上
  • (超详细)语音信号处理之特征提取
  • (附源码)ssm基于jsp的在线点餐系统 毕业设计 111016
  • (附源码)ssm考生评分系统 毕业设计 071114
  • (六)什么是Vite——热更新时vite、webpack做了什么
  • (一)utf8mb4_general_ci 和 utf8mb4_unicode_ci 适用排序和比较规则场景
  • (转)Android学习系列(31)--App自动化之使用Ant编译项目多渠道打包
  • (转)http协议
  • (自适应手机端)响应式新闻博客知识类pbootcms网站模板 自媒体运营博客网站源码下载
  • .chm格式文件如何阅读
  • .Mobi域名介绍
  • .NET 5种线程安全集合
  • .Net Core缓存组件(MemoryCache)源码解析
  • .NET Framework .NET Core与 .NET 的区别