ujson cannot handle long values correctly
See original GitHub issueIssue Description
I noticed that when getting numeric values out of a JSON, you can only retrieve the number as a double using the num
method. So if I know that I’m dealing with an 64-bit integer, my only option is to do this:
val id = json("some_64_bit_integer").num.toLong
(Also tried .string.toLong
, but that resulted in a runtime error because numeric values cannot be queried as strings)
The problem is that this only works reliably up to 53-bit integers, above that we’ll silently lose precision! Meaning that there will be no indication of any error whatsoever, but values greater than 2^53 will be just wrong!
One possible solution to this would be to have different methods for all numeric Java datatypes, so byte
, short
, int
, long
, float
and double
instead of just num
. We could still use the wrong method and then precision would be potentially lost, but at least then we’d have the option to get the correct values out if we used the correct method.
Additionally, in theory numeric JSON values can represent big numbers as well that cannot fit into the signed 64-bit range of a Java long
. So ideally we’d have a bigDecimal
method as well.
Check this for a more detailed explanation on the issue (it’s a JavaScript related writeup, but don’t let that confuse you, they are apparently facing the same precision problems in JS-land because they only have doubles natively 😃).
Issue Analytics
- State:
- Created 4 years ago
- Comments:5 (3 by maintainers)
But JavaScript is shit and we should do better, IMHO 😎
@radekm that behavior is expected.
ujson.Value
follows Javascript semantics, which behaves as shown on large numbers. You can useupickle.default.Read[Map[String, Long]]
for your example, or use a different AST (https://www.lihaoyi.com/upickle/#OtherASTs) if you want a more precise AST structure (at the expense of performance and other things).