minetest.serialize: Reversible number serialization (#9722)
authorHybridDog <3192173+HybridDog@users.noreply.github.com>
Wed, 22 Apr 2020 14:43:48 +0000 (16:43 +0200)
committerGitHub <noreply@github.com>
Wed, 22 Apr 2020 14:43:48 +0000 (16:43 +0200)
* minetest.serialize: Reversible number to string conversion

The %a format is not supported in Lua 5.1.
This commit also adds two tests for number serialization.

builtin/common/serialize.lua
builtin/common/tests/serialize_spec.lua

index 163aa67addb3552abada9479982bd0df581d8d7a..300b394c63166fa2086d2263be989c0b502d031b 100644 (file)
@@ -120,15 +120,8 @@ function core.serialize(x)
                elseif tp == "function" then
                        return string.format("loadstring(%q)", string.dump(x))
                elseif tp == "number"   then
-                       -- Serialize integers with string.format to prevent
-                       -- scientific notation, which doesn't preserve
-                       -- precision and breaks things like node position
-                       -- hashes.  Serialize floats normally.
-                       if math.floor(x) == x then
-                               return string.format("%d", x)
-                       else
-                               return tostring(x)
-                       end
+                       -- Serialize numbers reversibly with string.format
+                       return string.format("%.17g", x)
                elseif tp == "table" then
                        local vals = {}
                        local idx_dumped = {}
index c41b0a3728e1bede9afcaf5aa4a564d13f90d0cc..17c6a60f7db6f8f39c444ad6b377209e06ef8496 100644 (file)
@@ -18,6 +18,18 @@ describe("serialize", function()
                assert.same(test_in, test_out)
        end)
 
+       it("handles precise numbers", function()
+               local test_in = 0.2695949158945771
+               local test_out = core.deserialize(core.serialize(test_in))
+               assert.same(test_in, test_out)
+       end)
+
+       it("handles big integers", function()
+               local test_in = 269594915894577
+               local test_out = core.deserialize(core.serialize(test_in))
+               assert.same(test_in, test_out)
+       end)
+
        it("handles recursive structures", function()
                local test_in = { hello = "world" }
                test_in.foo = test_in