NumberValue not reaching 0, it gets "infinite"

Hello, I made a GUI system which shows cooldown.

I wanted to add decimals to the numbers, however, I got a strange bug

local current = 5 -- cooldown is 5 (example)
	for i = 1, current*10 do
		current -= 0.1
		MoveCooldown.Text = current
		wait(0.1)
	end

After the loop ends, it should make current = 0, but it makes it 1.0269562977783e-15

prints:

02:07:26.858 in loop 0.5 - Client - Inputs:133
02:07:26.958 in loop 0.4 - Client - Inputs:133
02:07:27.073 in loop 0.3 - Client - Inputs:133
02:07:27.174 in loop 0.2 - Client - Inputs:133
02:07:27.292 in loop 0.1 - Client - Inputs:133
02:07:27.407 in loop 1.0269562977783e-15 - Client - Inputs:133
02:07:27.524 after 1.0269562977783e-15 - Client - Inputs:137

I couldn’t upload an image, idk why

This didn’t happen without decimals.

Try this:

for i = 1, current*10 do
    if current == 0.1 then
        wait(.1)
        current = 0
        MoveCooldown.Text = current
        break
    end
	current -= 0.1
	MoveCooldown.Text = current
	wait(0.1)
end

still happens, i added prints and never reaches 0, in the cooldown GUI it still shows 1.0269562977783e-15

Maybe, this can help

local current = 5

for i = 1, current*10 do
	if current == 1 then
		current = 0
        MoveCooldown.Text = current / 10
		break
	end
	current -= 1
	MoveCooldown.Text = current / 10
	wait(.1)
end

I think it is a floating point error. Instead of doing this with decimal, try doing it with integers and then divide it.

2 Likes

This seems to be a reoccuring issue with different numbers, according to this old thread, with an explanation by Osyris.

In short, you might want to consider implementing (or taking, they’re available on the internet in public domain) a system which rounds out numbers for you as a possible solution. Hope I helped.

local current = 5 -- cooldown is 5 (example)
	for i = 1, current*10 do
		current -= 0.1
		MoveCooldown.Text = current
		wait(0.1)
		if i == 0.1 then
			break
		end
	end

You could do this if the last number is important but the next to last isn’t. It gives you the same 50 iterations but ends in 0.

local timeStep = 0.1
local current = 5-timeStep -- cooldown is 5 (example)
for i = 1, current*(1/timeStep)+1 do
	current -= math.min(timeStep,current)
	MoveCooldown.Text = current
	wait(timeStep)
	print(i, current)
end

or if you want nice numbers there is counting up time.

local n = 0
local timeStep = 0.1
local current = 5 -- cooldown is 5 (example)
for i = timeStep, current, timeStep do
	n += 1
	MoveCooldown.Text = i
	wait(timeStep)
	print(n, i)
end

P.S. I used a variable for your counter speed and converted all the numbers. Hope it isn’t confusing. Lets you change the speed with one number change. :slight_smile:

Thanks for the help guys but I couldn’t fix it in a “Correct way” what I did is:

for i = 1, current*10 do
	wait(0.1)
	current -= 0.1
	MoveCooldown.Text = current
end
MoveCooldown.Text = 0

It isn’t the way I wanted to fix it but for now I will stick with it. Thanks!

This may be the result you are looking for.

local current = 5
local step = .1
local decimalPlaces = 1

for i = 1, current*10 do
	current -= step
	if current < step then
		current = 0
        	MoveCooldown.Text = 0
	else
		MoveCooldown.Text = string.format("%."..decimalPlaces.."f", current)	
	end	
	wait(0.1)
end

If you are ok with the text displaying 0.0 then you can just remove the MoveCooldown.Text = 0

Although any solution is generally accepted with floating point issues. Just depends what you are preferring.