From 28857841aa8e7f7865d1cbabdfbd46e9be23cb1c Mon Sep 17 00:00:00 2001
From: kromka-chleba <65868699+kromka-chleba@users.noreply.github.com>
Date: Mon, 24 Jun 2024 19:57:06 +0000
Subject: [PATCH] Fix math.round floating point bug (#14757)

---
 builtin/common/misc_helpers.lua            | 11 +++++++----
 builtin/common/tests/misc_helpers_spec.lua | 14 ++++++++++++++
 2 files changed, 21 insertions(+), 4 deletions(-)

diff --git a/builtin/common/misc_helpers.lua b/builtin/common/misc_helpers.lua
index 424eb26d2..5e550348d 100644
--- a/builtin/common/misc_helpers.lua
+++ b/builtin/common/misc_helpers.lua
@@ -240,12 +240,15 @@ function math.factorial(x)
 	return v
 end
 
-
 function math.round(x)
-	if x >= 0 then
-		return math.floor(x + 0.5)
+	if x < 0 then
+		local int = math.ceil(x)
+		local frac = x - int
+		return int - ((frac <= -0.5) and 1 or 0)
 	end
-	return math.ceil(x - 0.5)
+	local int = math.floor(x)
+	local frac = x - int
+	return int + ((frac >= 0.5) and 1 or 0)
 end
 
 local formspec_escapes = {
diff --git a/builtin/common/tests/misc_helpers_spec.lua b/builtin/common/tests/misc_helpers_spec.lua
index 73a66737f..65549c2e3 100644
--- a/builtin/common/tests/misc_helpers_spec.lua
+++ b/builtin/common/tests/misc_helpers_spec.lua
@@ -176,3 +176,17 @@ describe("formspec_escape", function()
 		assert.equal("\\[Hello\\\\\\[", core.formspec_escape("[Hello\\["))
 	end)
 end)
+
+describe("math", function()
+	it("round()", function()
+		assert.equal(0, math.round(0))
+		assert.equal(10, math.round(10.3))
+		assert.equal(11, math.round(10.5))
+		assert.equal(11, math.round(10.7))
+		assert.equal(-10, math.round(-10.3))
+		assert.equal(-11, math.round(-10.5))
+		assert.equal(-11, math.round(-10.7))
+		assert.equal(0, math.round(0.49999999999999994))
+		assert.equal(0, math.round(-0.49999999999999994))
+	end)
+end)