3

In my engine I have a Lua VM for scripting. In the scripts, I write things like:

stage = stage + 1
if (stage == 5) then ... end

and

objnum = tonumber("5")
if (stage == objnum)

According to the Lua sources, Lua uses a simple equality operator when comparing doubles, the internal number type it uses.

I am aware of precision problems when dealing with floating point values, so I want to know if the comparison is safe, that is, will there be any problems with simply comparing these numbers using Lua's default '==' operation? If so, are there any countermeasures I can employ to make sure 1+2 always compares as equal to 3? Will converting the values to strings work?

GhassanPL
  • 2,679
  • 5
  • 32
  • 40
  • 2
    possible duplicate of [if lua number is double, does =/<=/>= operations always correct?](http://stackoverflow.com/questions/10526615/if-lua-number-is-double-does-operations-always-correct) – Nicol Bolas Sep 07 '12 at 13:44

4 Answers4

14

You may be better off by converting to string and then comparing the results if you only care about equality in some cases. For example:

> print(21, 0.07*300, 21 == 0.07*300, tostring(21) == tostring(0.07*300))
21      21      false   true

I learned this hard way when I gave my students an assignment with these numbers (0.07 and 300) and asked them to implement a unit test that then miserably failed complaining that 21 is not equal 21 (it was comparing actual numbers, but displaying stringified values). It was a good reason for us to have a discussion about comparing floating point values.

Paul Kulchenko
  • 25,884
  • 3
  • 38
  • 56
  • this example is why it is a very good reason to use math.floor() on calculated values where precision may be an issue and isn't important. – Mike Corcoran Sep 08 '12 at 00:42
2

I can employ to make sure 1+2 always compares as equal to 3?

You needn't worry. The number type in Lua is double, which can hold many more integers exactly than a long int.

Mud
  • 28,277
  • 11
  • 59
  • 92
1

Comparison and basic operations on doubles is safe in certain situations. In particular if the numbers and their result can be expressed exactly - including all low value integers.

So 2+1 == 3 will be fine for doubles.

NOTE: I believe there's even some guarantees for certain math functions ( like pow and sqrt ) and if your compiler/library respects those then sqrt(4.0)==2.0 or 4.0 == pow(2.0,2.0) will reliably be true.

Michael Anderson
  • 70,661
  • 7
  • 134
  • 187
1

By default, Lua is compiled with c++ floats, and behind the scenes number comparisons boils down to float comparisons in c/c++, which are indeed problematic and discussed in several threads, e.g. most-effective-way-for-float-and-double-comparison.

Lua makes the situation only slightly worse by converting all numbers, including c++ integers, into floats. So you need to keep it in mind.

Community
  • 1
  • 1
Uri Cohen
  • 3,488
  • 1
  • 29
  • 46