How to round places based on number

25.25237637637
0.0000001

if I have these 2 numbers, how can I round the 25 one to 1 decimal place

25.3

but then the other to show the full %?

2 Likes

tonumber isnt really required here just so you know, if you have a number as the Argument, it will remain as a number, so you dont need to convert a number into something that it already is, plus, you can also just do it with strings, I tested it and it works:

print(roundNumber("13213.213")) --> 13213.2
2 Likes

I need it to return
0.0000001. It should only round if number is idk, above 0.01% optherwise i need all the 0s present

1 Like

Btw, your method is actually really slower than others, I made sure to test their speeds and this was the code I tested for this:

local normal = Random.new():NextNumber(90, 100) -- a number at random
-- to keep track of results
local xres 
local yres

local start = os.clock() -- start time
for i = 1,1e4 do
	xres = ("%.1f"):format(normal) -- string.format
end

local speed = os.clock() - start -- subtracts the current time with the started time

print(speed, xres, "string.format")


local start = os.clock() -- start time
for i = 1,1e4 do
	yres = math.round(normal) -- math.round()
end

local speed = os.clock() - start -- subtracts the current time with the started time

print(speed, yres, "math.round()")

Output after many Attempts;

0.003312999993795529 98324325.0 "string.format"  -  Server - Script:18
0.0001275000104214996 98324324 "math.round()"  -  Server - Script:30

Which as you can see, its sort of a Big Difference

And yes, I did this:

xres = string.format("%.1f", normal)
yres = math.floor(normal*10)/10

string.format is still slower, plus math.floor was more accurate

function round(num)
  local precision = 1
  while true do
    local rounded = math.floor(num*10 * precision + 0.5) / precision/10
    if rounded ~= 0 then
      return rounded
    end
    precision = precision * 10
  end
end
1 Like

um yeah, basically a useless function, math.round() exists

math.round(num)

Plus, this method is actually 2 - 3 times slower than math.round()

why not utilise the math.round() function?

edit: just realised the previous reply was to do with math.round(),
was busy just reading through the topic…

1 Like

you should read the question well before you judge. The documentation says that math.round rounds to integers not to one decimal place.

I have, and i was here saying that there is a faster method then string.format if you actually read what I was doing.

so does your code, whats your point?

you didn’t try my code, it does exactly what OP asks for.

print(round(25.25237637637))  --> output: 25.3
print(round(0.0000001))      --> output: 0.0000001

this seems to be made up

That isnt actually what he is asking either, he is asking to round TO the decimal, from 25 to .0000001

It is clear. You are wrong.___

1 Like

round 25 to the 1 decimal place
I’m not going to argue here btw, PM me for that

Dunno about speed, but you can do it all in a single line:

Rounded = ToRound > 0.01 and string.format("%.1f", ToRound) or ToRound
1 Like

You haven’t really defined what you want very well. How do you want these numbers formatted?

0.000000002525237637637
0.00000002525237637637
0.0000002525237637637
0.000002525237637637
0.00002525237637637
0.0002525237637637
0.002525237637637
0.02525237637637
0.2525237637637
2.525237637637
25.25237637637
252.5237637637
2525.237637637
25252.37637637
252523.7637637
1 Like

i would rather do

local table = {Number = 25.35237637637, Decimals = 3}

local function Round(number, decimalPlaces)
	return tonumber(string.format("%."..(decimalPlaces or 0).."f", number))
end

print(Round(table.Number, table.Decimals))

Let me preface this with the fact that I’d realistically just go with the string.format() method in most cases because it’s the most simplistic approach to this problem.

Luz and Poppy’s answers are both correct. What OP wants is, seemingly, for floats >= 1 to be rounded to 1 d.p. and anything < 1 to be left alone.

As far as performance is concerned, it’s only one order of magnitude slower than using math.round(), which for the record does not do what OP asked for, making it irrelevant to the topic. Even if it is objectively “slower”, your suggested implementation is still incorrect as it does not provide the answers which OP wants.

Upon writing a Lua script and running it in the online Lua 5.4.4 test environment, we can see that your solution(s) are actually less accurate than string.format() using the following code:

NOTE: Lua 5.4.4 does not have support for math.round(), so I wrote it using floor(n+0.5), which is functionally identical.


local floor_pts = 0;
local strf_pts = 0;
local round_pts = 0;
local ties = 0;
local iters = 0;

for i = 1, 1000, 0.1 do
    local n = i/100;

    local floor_ans = math.floor(n*10)/10;
    local strf_ans = tonumber(string.format("%.1f", n));
    local round_ans = math.floor(n+0.5); -- math.round() is not in lua 5.4.4 yet, but functionally identical

    local floor_err = math.abs(n-floor_ans);
    local strf_err = math.abs(n-strf_ans);
    local round_err = math.abs(n-round_ans);

    if floor_err < strf_err and floor_err < round_err then
        floor_pts = floor_pts + 1;
    elseif strf_err < floor_err and strf_err < round_err then
        strf_pts = strf_pts + 1;
    elseif round_err < floor_err and round_err < strf_err then
        round_pts = round_pts + 1;
    else
        ties = ties + 1;

        --uncomment below to learn when all values produce identical outputs
        --[[
        print("n:\t\t"..n);
        print("floor_ans:\t"..floor_ans);
        print("strf_ans:\t"..strf_ans);
        print("round_ans:\t"..round_ans);
        print("\n");
        --]]
    end

    iters = iters + 1;
end

print("Cases where math.floor() was most accurate: " .. floor_pts);
print("Cases where string.format() was most accurate: " .. strf_pts);
print("Cases where math.round() was most accurate: " .. round_pts);
print("Cases where all 3 methods produced the same output: " .. ties);
print("Total iterations: "..iters);

Running this, we get the following:

For 9990 iterations, string.format() was most accurate for 4500 iterations, or in other words, was accurate roughly 45% of the time, whereas all three methods produced the same output around 54.95% of the time. In no cases were math.floor() or math.round() more accurate than string.format().

Now, we can use some basic mathematics associated with the laws of the base 10 number system to arrive with the following function for rounding to n decimal places:

local function desired_round(num, dp)
    local mult = 10^dp;
    return math.floor(num * mult + 0.5) / mult;
end

In doing so, we get a purely mathematical, functionally identical replacement for the string.format() method.

Through rigor, we can prove they are functionally identical:

For 9990 iterations, both desired_round() and string.format() produced the same results 100% of the time.

Now, to answer OP’s question, if they don’t want to use the string.format() method, the following will produce the results they are looking for:

local function desired_round(num, dp)
    local mult = 10^dp;
    return num >= 1
           and math.floor(num * mult + 0.5) / mult
           or num;
end

Using the online Lua interpreter once again, we can see results aligning with OP’s original post.

NOTE: string.format() was only used to prevent the interpreter from outputting the number in scientific notation. The result is unaltered.