ddk
ddk

Reputation: 1833

Lua: converting from float to int

Even though Lua does not differentiate between floating point numbers and integers, there are some cases when you want to use integers. What is the best way to covert a number to an integer if you cannot do a C-like cast or without something like Python's int?

For example when calculating an index for an array in

idx = position / width

how can you ensure idx is a valid array index? I have come up with a solution that uses string.find, but maybe there is a method that uses arithmetic that would obviously be much faster. My solution:

function toint(n)
    local s = tostring(n)
    local i, j = s:find('%.')
    if i then
        return tonumber(s:sub(1, i-1))
    else
        return n
    end
end

Upvotes: 49

Views: 157200

Answers (5)

Flare
Flare

Reputation: 83

Hofstads answer is great however, it doesn't work well with negative numbers to make it similar to python's int function.

Here is a version that works with negative numbers:

local function toint(f)
   if f > 0 then
      return math.floor(f)
   else
      return math.ceil(f)
   end
end

Side Note of using math.abs instead.:

The math.abs solution works as well. You might think running this -math.floor(math.abs) (extra function call and using the math.abs function) might make it the math.abs solution slower. However with LuaJit I didn't notice any performance difference, so use any solution you'd like. The above solution might work better with most versions of lua though.

Upvotes: 0

Cody
Cody

Reputation: 161

@Hofstad is correct with the math.floor(Number x) suggestion to eliminate the bits right of the decimal, you might want to round instead. There is no math.round, but it is as simple as math.floor(x + 0.5). The reason you want to round is because floats are usually approximate. For example, 1 could be 0.999999996

12.4 + 0.5 = 12.9, floored 12

12.5 + 0.5 = 13, floored 13

12.6 + 0.5 = 13.1, floored 13

local round = function(a, prec)
    return math.floor(a + 0.5*prec) -- where prec is 10^n, starting at 0
end

Upvotes: 16

lin
lin

Reputation: 1589

Lua 5.3 introduced a new operator, called floor division and denoted by //

Example below:

Lua 5.3.1 Copyright (C) 1994-2015 Lua.org, PUC-Rio

>12//5

2

More info can be found in the lua manual

Upvotes: 26

Necrolis
Necrolis

Reputation: 26171

why not just use math.floor()? it would make the indices valid so long as the numerator and denominator are non-negative and in valid ranges.

Upvotes: 3

Hofstad
Hofstad

Reputation: 1061

You could use math.floor(x)

From the Lua Reference Manual:

Returns the largest integer smaller than or equal to x.

Upvotes: 89

Related Questions