Skip to content

Support for numbers outside of IEEE754 double precision range #160

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
bravehorsie opened this issue Mar 1, 2019 · 14 comments
Closed

Support for numbers outside of IEEE754 double precision range #160

bravehorsie opened this issue Mar 1, 2019 · 14 comments

Comments

@bravehorsie
Copy link
Contributor

JSONP API JsonGenerator / JsonParser types expose methods for reading / writing numbers which can contai values outside of IEEE754 double precision allows. These are:

java.math.BigDecimal, java.math.BigInteger and java.lang.Long

Currently JSONP doesn't offer anything different than writing them as JSON number type. This may cause ECMAScript based parsers to loose precision when parsing these numbers. The proposal is to introduce a "big number strategy" into JSONP API which will allow users to configure how to handle these numbers.

/**
* (Subject to change at this point)
* Specifies how to handle number types, which can contain values outside of range supported
* by ECMAScript, eg. IEEE754 double-precision range.
*/
public enum NumberStrategy {
    /**
    * Writes values always as JSON number type.
    */
    JSON_NUMBER,

    /**
    * Writes values always as JSON string type.
    */
    JSON_STRING,

    /**
    * Checks the actual value of the number, if it is in IEEE754 double-precision range
    * write JSON number, otherwise write JSON string.
    */
    ADAPTIVE_NOTATION;
}

This configuration should be propagated through javax.json.stream.JsonGeneratorFactory / javax.json.stream.JsonParserFactory, which contains other configuration mapping such as JsonGenerator.PRETTY_PRINTING. The default strategy to use should be JSON_NUMBER.

References:
[1] https://www.ecma-international.org/ecma-262/9.0/index.html#sec-ecmascript-language-types-number-type
[2] jakartaee/jsonb-api#112
[3] https://github.com/cyberphone/I-JSON-Number-System#java-json-b
[4] https://github.com/eclipse-ee4j/yasson/blob/master/src/main/java/org/eclipse/yasson/internal/serializer/BigNumberUtil.java

@bravehorsie
Copy link
Contributor Author

ADAPTIVE strategy is not implemented in the PR.

@nimo23
Copy link

nimo23 commented Aug 14, 2019

Please provide something like:

JsonGenerator write(Double value);

to process Double values in a correct and complete manner.

Actually, Json-P does ignore valid information of a Double and is NOT able to produce NaN and Infinity side by side with Double values.

The NaN or Infinty is still a valid information about a Double!

How should one know beforehand when a Double is NaN or not? Json-P should not stop to (de)serialize a Double if the value is NaN or Infinity. The information about the Double value should be propagated to the json string and vice versa! That would be the correct and complete way.

Something like this is actually impossible with Json-P and therefore also with Json-B:

{
  "val1" : "NaN",
  "val2" : 1.0,
  "val3" : 0.0,
  "val4" : "Infinity"
}

I actually looked at what Jackson makes with such values. Jackson does what it should and can (de)serialize NaN and Infinity. Actually, I cannot use Json-B because it cannot handle Double values complete and correct - because Json-P cannot handle it. Please consider to provide NaN and Infinity within a Double value.

@bravehorsie
Copy link
Contributor Author

@nimo23 I am not able to further help with this issue. @lukasj is there any interest on jsonp side to carry this further?

@alexsm82
Copy link

alexsm82 commented Aug 15, 2019

I think we should be able to resolve @nimo23 's comment by updating the Javadoc to remove the requirement that NaN and Infinity throw a NumberFormatException (and updating the Impl/TCK accordingly). I can put together a PR with those changes.

@leadpony
Copy link
Contributor

The JSON grammar does not allow NaN and Infinity to be represented and this change may produce JSON which is not interchangeable between various kinds of platforms.

RFC 8259 states:

Numeric values that cannot be represented in the grammar below (such as Infinity and NaN) are not permitted.

The feature can be configured with an option WRITE_NAN_AS_STRINGS in Jackson.

@alexsm82
Copy link

Thanks for pointing that out. I had assumed it was valid JSON as it was mentioned to work in Jackson. I suppose we could add an option to support this behavior, but that could reasonably also be done in individual implementations rather than mandated by the spec. We are getting somewhat sidetracked from the issue here so if you'd like you can open a separate issue for discussion on this @nimo23.

@m0mus
Copy link
Contributor

m0mus commented Aug 26, 2019

JSONP is a low-level parser. I don't think that it should contain this kind of logic. IMO, it should be done on a higher level (read JSONB).

@m0mus
Copy link
Contributor

m0mus commented Aug 26, 2019

@nimo23 JSONP writes numbers as it's defined in JSON RFC. "NaN" and "Infinity" are not numbers but strings from JSON perspective. The functionality you suggesting could be a part of higher level binding framework though.

@nimo23
Copy link

nimo23 commented Aug 26, 2019

@m0mus yes, this is what I also think.

Such things should be definitly go to Json-B, because B stands for Binding and actually the binding between java numbers and json processing is not complete. Therefore, I asked for that in eclipse-ee4j/yasson#306 before, but it was market as duplicated and closed with the reason that this should be done in lower level (json-p). Hence, I created I #209. But in my opinion, Json-B must support full binding of Numbers.

@m0mus
Copy link
Contributor

m0mus commented Aug 26, 2019

@nimo23 I reopened eclipse-ee4j/yasson#306

@m0mus
Copy link
Contributor

m0mus commented Aug 26, 2019

Closing this issue. If someone wants to discuss it more -> reopen.

@m0mus m0mus closed this as completed Aug 26, 2019
@keilw
Copy link
Member

keilw commented Aug 27, 2019

@m0mus then what about #99, does it apply to that question or issue as well?

@bravehorsie bravehorsie reopened this Aug 27, 2019
@bravehorsie
Copy link
Contributor Author

The original subject of this issue and a pull request attached to it is completely different of what @nimo23 started to talk about.

@m0mus
Copy link
Contributor

m0mus commented Aug 27, 2019

@bravehorsie I see this functionality unnecessary and I discussed it with you privately. If you need to write a number as string, JSONP has methods to write strings.

@m0mus m0mus closed this as completed Aug 27, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants