Simple Round

lua-users home
wiki

The following function rounds a number to the given number of decimal places.

function round(num, idp)

  local mult = 10^(idp or 0)

  return math.floor(num * mult + 0.5) / mult

end

Here is an alternative implementation:

function round2(num, idp)

  return tonumber(string.format("%." .. (idp or 0) .. "f", num))

end

Both are Lua 5.0 and 5.1 compatible.

If the number is rounded in order to be printed, then remove the tonumber: Converting to number then back to string would reintroduce rounding errors.

Tests:


> function test(a, b) print(round(a,b), round2(a,b)) end

> test(43245325.9995, 3)

43245326        43245325.999

> test(43245325.9994, 3)

43245325.999    43245325.999

> test(43245325.5543654)

43245326        43245326

> test(43245325.5543654, 3)

43245325.554    43245325.554

> test(43245325.5543654, 4)

43245325.5544   43245325.5544

Note: The first function will misbehave if idp is negative, so this version might be more robust (Robert Jay Gould)


Actually i wanted it to round to 100s, so the negative cases are very useful and ok mathematically (no error there):

round(1023.4345, -2) = 1000

round(1023.4345, 2) = 1023.43

(Tom P.)
function round(num, idp)

  if idp and idp>0 then

    local mult = 10^idp

    return math.floor(num * mult + 0.5) / mult

  end

  return math.floor(num + 0.5)

end


function round(num) return math.floor(num+.5) end

-- Rob

Might have unintended result for -.5? Please see below.

-- Henning


Round towards zero
    function round(num) 

        if num >= 0 then return math.floor(num+.5) 

        else return math.ceil(num-.5) end

    end

Note that math.ceil(num-.5) ~= math.floor(num+.5) e.g. for -.5 with math.ceil(num-.5) == -1 math.floor(num+.5) == 0

Samples: 1.1 -> 1, 1 -> 1, 0.9 -> 1, 0.5 -> 1, 0.1 -> 0, 0 -> 0, -0.1 -> 0, -0.4 -> 0, -0.5 -> -1, -0.6 -> -1, -0.9 -> -1, -1: -1, -1.1: -1

-- Henning


function round(num)

    under = math.floor(num)

    upper = math.floor(num) + 1

    underV = -(under - num)

    upperV = upper - num

    if (upperV > underV) then

        return under

    else

        return upper

    end

end


Combined from above - Round towards 0 with precision:
function round(num, idp)

    local mult = 10^(idp or 0)

    if num >= 0 then return math.floor(num * mult + 0.5) / mult

    else return math.ceil(num * mult - 0.5) / mult end

end

-- Igor Skoric (i.skoric@student.tugraz.at)


I've made a small implementation for my game:
function round(n, mult)

    mult = mult or 1

    return math.floor((n + mult/2)/mult) * mult

end


Pan Handles negatives mod >Original above

--should round and give negatives too if I'm not mistaken

function round(num, idp)

  if idp and idp>0 then

    local mult = 10^idp

    return math.floor(num * mult + 0.5) / mult

  else

    idp = idp mult 2 -- negates its negative status

    local mult = 10^idp

    return math.floor(num * mult + 0.5) / mult

    ide = idp / (idp/2)

  end

  return math.floor(num + 0.5)

end


My lack of lua skills has helped me on this, not understanding half of the above.

Math.modf is your friend!

if num<0 then x=-.5 else x=.5 end

Integer, decimal = math.modf(num+x)

Integer will then = num, rounded positive and negative.

For rounding to a decimal place I use

roundto=10

if num*roundto<0 then x=-.5 else x=.5 end

Integer, decimal = math.modf(num*roundto+x)

result = Integer/roundto

result will equal number rounded to the decimal place "roundto"

-zardOz, come play Principia! We need more good Lua coders!


RecentChanges · preferences
edit · history
Last edited February 25, 2014 4:30 am GMT (diff)