JSONEncode doesn't Encode math.huge

Expected behavior is that it saves math.huge
(since Datastore also encodes Data in JSON format and can save math.huge)

local HttpS = game:GetService('HttpService')

local Encode = HttpS:JSONEncode({Boolean = true, Number = math.huge})
local Decode = HttpS:JSONDecode(Encode)

for i,v in pairs(Decode) do
	print(i,v)
end

print(Decode.Number)

-- Output
>  Boolean true
>  nil

(copy and paste it in command bar to reproduce)



2 Likes

Interestingly, in JavaScript’s JSON encoder, it does this too.

JSON.stringify(Infinity) === "null"

Integer.MAX_VALUE works though.

I bring this up because I would consider JavaScript’s JSON system to be the baseline for most encoders/decoders. So I wonder if it’s intentional that math.huge is encoded as nil?

Edit: There is no mention of Infinity on the official JSON spec, which is why it’s encoded as null.

2 Likes

Yep; if you do

local HttpS = game:GetService('HttpService')

local Encode = HttpS:JSONEncode({Boolean = true, Number = math.huge}) 

print(Encode);

Output
> {"Number":null,"Boolean":true}

@Crazyman32, I do need a solution for this, if you have a clever idea for a quick fix please kindly let me know.

My first suggestion would be not to store math.huge in your data. What’s the use case that you need this for?

3 Likes

Could you not just tostring(math.huge) for encoding and then do tonumber(table.Number) whenever you need it? I’m also curious for the use case for this.

3 Likes

That’s because it’s a bad idea to try to save math.huge as a string. There’s no technically no guarantee that math.huge even means the same value in two different Lua environments (it’s entirely possible to compile a Lua build which uses 32 bit floats rather than doubles for the number type).

You should serialize what you’re actually trying to represent data wise, which is probably not infinity.

1 Like

I understand, but consider this

I tried converting math.huge using tostring and then tonumber it came out fine, so internally if it would convert math.huge to string as INF then everything should be fine, this shouldn’t be a problem because you can send math.huge over the network meaning it can and already is being serialized.

using math.huge is somewhat rare but it’s simple to use for representing Infinity, game development is already very complicated and sometimes I just want to use math.huge to keep things simple, yes there are work arounds but they are messy and complex, and if you aren’t suppose to use math.huge why does it exist in the first place?

Fair, the fact that the API is inconsistent is bad, and should probably be fixed. I’m just pointing out that if you run into this problem at all you’ve probably already made a bad decision in serializing some state more directly than you should have.

If your number doesn’t ever reach a certain value (e.g. -1) you can just interpret that as math.huge.

What exactly is the value being sent for? I agree with stravant that you probably shouldn’t need to use something like math.huge for most use cases. Would a boolean flag (e.g. isUnlimited) suit your purpose better?

I want to reiterate a point I made earlier: Representing infinity isn’t supported in the JSON spec, so this isn’t going to be changed. Roblox won’t change it because keeping to the spec is important in respect to making web requests that accept and return JSON payloads.

So unfortunately the only solution for your problem here is to change the way you are representing the information.

I understand, it’s not a big issue as there are simple fixes like using tostring and tonumber so I’m not worried about Roblox fixing it or not.

but it should at least be reported and documented so other people can find resources and solutions to solve it.

Thank you for the insight.

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.