GhassanPL
GhassanPL

Reputation: 2724

How safe is comparing numbers in lua with equality operator?

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?

Upvotes: 5

Views: 17238

Answers (4)

Mud
Mud

Reputation: 28991

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.

Upvotes: 1

Paul Kulchenko
Paul Kulchenko

Reputation: 26744

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.

Upvotes: 14

Uri Cohen
Uri Cohen

Reputation: 3608

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.

Upvotes: 1

Michael Anderson
Michael Anderson

Reputation: 73470

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.

Upvotes: 1

Related Questions