diff --git a/builtin/common/misc_helpers.lua b/builtin/common/misc_helpers.lua index 04ea9c486..54b24fe52 100644 --- a/builtin/common/misc_helpers.lua +++ b/builtin/common/misc_helpers.lua @@ -7,7 +7,15 @@ local math = math local function basic_dump(o) local tp = type(o) if tp == "number" then - return tostring(o) + local s = tostring(o) + if tonumber(s) == o then + return s + end + -- Prefer an exact representation over a compact representation. + -- e.g. basic_dump(0.3) == "0.3", + -- but basic_dump(0.1 + 0.2) == "0.30000000000000004" + -- so the user can see that 0.1 + 0.2 ~= 0.3 + return string.format("%.17g", o) elseif tp == "string" then return string.format("%q", o) elseif tp == "boolean" then diff --git a/builtin/common/tests/misc_helpers_spec.lua b/builtin/common/tests/misc_helpers_spec.lua index d24fb0c8f..43639ccbb 100644 --- a/builtin/common/tests/misc_helpers_spec.lua +++ b/builtin/common/tests/misc_helpers_spec.lua @@ -230,3 +230,10 @@ describe("math", function() assert.equal(0, math.round(-0.49999999999999994)) end) end) + +describe("dump", function() + it("avoids misleading rounding of floating point numbers", function() + assert.equal("0.3", dump(0.3)) + assert.equal("0.30000000000000004", dump(0.1 + 0.2)) + end) +end)