Skip to content

JSON precision loss on copyCurrentEvent() for floats that require greater than double precision #730

@htmldoug

Description

@htmldoug

Feature Request

I'd like a way to determine if getNumberType() is guaranteed to return an exact response or might lose precision if parsed to the corresponding native type.

Motivation

The JSON JsonParsers always return NumberType.DOUBLE -- never FLOAT or BIGDECIMAL. Consequently, I've been (incorrectly) parsing all JSON JsonToken.VALUE_NUMBER_FLOAT as doubles, losing precision for anything that doesn't fit. These comments suggest that the reason for always returning DOUBLE is that BigDecimal parsing is expensive, so it's up to the jackson-core consumer to ask for one if they want it.

As a user of the JsonParser I don't know if I want a BigDecimal at the point I interact with the JsonParser. I'm pushing the value downstream to be interpreted later. I'd like to get either a primitive float/double or else a CharSequence. This is the approach I'm taking in rallyhealth/weePickle#102.

However, converting all floats to strings is suboptimal when used with jackson-dataformats-binary. SmileParser knows that a double-tagged value (0x29) is 100% guaranteed to fit in a primitive double, but I have to convert it to a base10 string (and probably back to a base2 double later), since I can't trust getNumberType's answer of DOUBLE.

I've found #631, but for JSON, it appears always to return BigDecimal even for values like 0.0 that would fit in a double. I've benched about a 50% throughput penalty for sending all floats through BigDecimal.

AFAICT, it is not possible to determine whether or not to trust getNumberType() to avoid precision loss for any given JsonParser without hardcoding to its known behavior ahead of time (which may change in subsequent releases).

Proposal

I don't see a way to update the JSON JsonParser to return exact getNumberType() values without increasing upfront parsing cost, but if I had a signal that getNumberType() is trustworthy for a Smile JsonParser, but not for a JSON JsonParser, I could work around it. I would be able to ask for Strings for only non-exact values.

I think some method like boolean isNumberTypeGuaranteedExact() would satisfy my needs. Being able to ask for each token seems ideal. For the JSON JsonParser, it might return false for all JsonToken.VALUE_NUMBER_FLOAT.

WDYT? And especially, is there some other existing option that I've overlooked?

Thanks!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions