Luaはmath.floorを使用してバグを生成します



Lua Uses Math Floor Generate Bugs



前書き:

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 -- the problem occurs ]]

テスト:

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の数値型は実際には倍精度(倍精度浮動小数点型)であるため、小数の場合は特に注意する必要があります。2つの小数は等しいため、等号は使用できませんが、それらの絶対値は差は小さいものより小さくする必要があります。数(math.abs(a --b)など)<10e-6)! プログラムで2つの浮動小数点数を判断する方法

コンピュータはデータを2進数で格納し、0.1のような数値は非常に長い数値としてコンピュータに格納されるためです。バイナリでは、0.1は無限ループになる可能性があるため、ある程度インターセプトします。傍受後、必然的に実際の値と私たちが保存する値の間に非常に小さな違いが生じます!

これにより、5562.9999999997と5563が得られ、これらは私たちの意見では同じ数です。 math.floor(5562.9999999997)は5562に等しくなるように切り捨てられるため、math.floorの後に偏差があります。

同様に、math.ceilでも同じ問題が発生します。

したがって、Luaでmath.floorとmath.ceilを使用する場合は、この問題に注意を払う必要があります。

マークするだけ!