Lua How to tell 1 from 1.0

780 views Asked by At

I have a configuration script where the user can enter values either as an absolute value or a percentage value.

Absolute values are written as a value between 0.0 and 1.0 while percentage value are written as 0 to 100.

How can I distinguish 1 from 1.0? If I were to use strings, then it's not a problem for sure... I would like to keep this configuration simple and not have to rely strings.

Is this possible at all?

RECAP:

a = 1
b = 1.0

How to tell that a is not of the same type as b.

EDIT The configuration file look something like this:

local config = {}

-- A lot of comments describing how to configure

config.paramA = 1
config.paramB = 1.0

return config

In my processing script i read the configs like this:

config = require 'MyConfigFile'

config.paramA
config.paramB
4

There are 4 answers

3
Youka On BEST ANSWER

With Lua 5.3 came the integer data type which allows to differ between integer & floating point numbers and provides better performance in some cases. math.type is the function to get the subtype of a number.

local x = 1.0
print(math.type(x)) -- float
x = 1
print(math.type(x)) -- integer

If your percent value should be floating point too, William already called it: "a number is a number". You have to add an additional information to your number to differentiate, like packing it in a table with an identifier. Because you have just 2 cases, a boolean would be a cheap solution.

1
William Barbosa On

From PIL you can see that a number is a number and therefore there's no way to distinguish 1 from 1.0 when working with them because they do have the same type

A way to to solve your problem is using a table that contains both the value and the type:

config.paramA = { 1, 'i' }
config.paramB = { 1.0, 'd' }

Or using a string and parsing it before converting to an integer:

config.paramA = '1'
config.paramB = '1.0'
1
Paul Kulchenko On

With Lua 5.1 and 5.2 there is no difference, which can be seen from luac output (luac -i) as local a, b = 1, 1.0 generates the following code:

main <1.lua:0,0> (3 instructions, 12 bytes at 007D04E8)
0+ params, 2 slots, 0 upvalues, 2 locals, 1 constant, 0 functions
    1   [1] LOADK       0 -1    ; 1
    2   [1] LOADK       1 -1    ; 1
    3   [1] RETURN      0 1

Lua 5.3 allows to distinguish between the two using math.type as they have different subtypes.

As a solution to your particular problem, if you really want to make it a non-integer, you can probably add a very small delta to the number: 1.0000001 instead of 1.0.

2
ryanpattison On

some suggestions:

1) allow only one of the two formats

2) use a function to make the format explicit

config.paramA = percent(1.9)
config.paramB = portion(1)

those functions could create tables with type info or just convert the value to a consistent type