question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

How to serialize BigInteger and BigDouble?

See original GitHub issue

Currently I’m in the need of serializing numbers with many decimal digits (30+ decimal digits to be more precise). To deserialzie a JSON file with this many decimal points I used Java’s BigIntegers and BigDecimal types which works fine. The problem that arises is when I want to serialize that value. It will be serialized as an Integer or Double respectively which cuts and rounds the actual value.

One example value is this, received in a JSON file. 0.083532162010669708251953125000 After deserializing I will have exactly a value of that above as a JsonLiteral. But when I serialize this value I will get a result of: 0.08353216201066971 Which is not my desired result. A snippet from my unit tests showing the differences between expected and actual: image

My questions are now how should I serialized BigIntegers and BigDoubles and will there be support for this kind of data types in the future?

Issue Analytics

  • State:open
  • Created 3 years ago
  • Reactions:14
  • Comments:13 (4 by maintainers)

github_iconTop GitHub Comments

10reactions
tadfishercommented, Apr 1, 2021

As it is, there is no way to encode a JSON number outside of Kotlin’s primitive types, which means that it is impossible to encode a decimal value without inducing precision loss.

  • If you use encodeString, StreamingJsonEncoder will quote the value, regardless of the descriptor kind.
  • If you use encodeJsonElement with JsonPrimitive, the value’s string representation will be converted using String.toDoubleOrNull(), not only inducing precision loss but formatting the value using engineering notation (e.g. 1.11222333444E11).
  • There is no mechanism to encode an unquoted string value that I can find, using either Encoder or JsonEncoder.

Bear in mind that ECMA-404 does not specify that JSON numbers must represent IEEE-754 values; they are simply strings of digits with optional fraction and exponent parts. From json.org:

number
    integer fraction exponent

integer
    digit
    onenine digits
    '-' digit
    '-' onenine digits

digits
    digit
    digit digits

digit
    '0'
    onenine

onenine
    '1' . '9'

fraction
    ""
    '.' digits

exponent
    ""
    'E' sign digits
    'e' sign digits

sign
    ""
    '+'
    '-'

JsonEncoder should expose a mechanism to write an unquoted JSON number, which would solve this particular issue and allow for the use of non-Number types.

4reactions
MMairingercommented, Sep 21, 2020

Yes, in fact, directly converting them was my initial plan until I saw that you cannot directly serialize Any types. As you answered in some old issue that we should use JsonObject to serialize types of Map<String, Any> I then did the same thing for every other type that had Any in it, i.e. JsonArray for List<Any> and so on.

I also fideled around with custom serializers but I gave up eventually since I couldn’t get it to work. The easiest solution was for me to simply let kotlinx do the deserialization and then convert it with simple methods to standard kotlin types. Same goes for serialization.

Thanks for the answer, so I need a custom serializer for that.

Is it possible for the deserialization/serialization of BigInts/Doubles to become a feature in the future so we no longer need a custom serializer for very long numbers?

Read more comments on GitHub >

github_iconTop Results From Across the Web

java - What is the best approach for serializing BigDecimal ...
Yes. You should define BigInteger as BigInteger.toByteArray() . My guess is that BigDecimal would be: message BDecimal { required int32 ...
Read more >
Java ByteBuffer Serialize serializeBigDecimal(BigDecimal bd ...
Serialize the java.math.BigDecimal BigDecimal to Volt's fixed precision and scale 16-byte format. License. Open Source License. Parameter. Parameter ...
Read more >
Kryo serialization issues with BigInteger, BigDecimal ...
BigInteger, BigDecimal classes. I'm using the ObjectBuffer for the read/write from/to a io stream. I see that Kryo is failing to
Read more >
BigDecimal (Java Platform SE 7 ) - Oracle Help Center
BigDecimal. All Implemented Interfaces: Serializable, Comparable<BigDecimal> ... Translates a BigInteger unscaled value and an int scale into a BigDecimal .
Read more >
Custom Kotlin Serializer for BigDecimal - Woo Huiren
This treats BigInteger/BigDecimal values as strings in serialization; which may not be what one desires. For example: class MyClass(val ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found