"Stupid" JSON Number Serialization Question

# Anders Rundgren (6 years ago)

Please allow me wasting a little bit of your precious time on a topic which doesn't appear to be completely agreed upon.

As you know JSON Numbers in ECMAScript are currently limited to IEEE-754 Double Precision.

To support interoperability with JSON.parse(), providers of JSON tools for other platforms have taken somewhat different paths when dealing with BigInteger, Long, Money, BigNumber, etc.

One camp headed by the JDK (Java) folks advocates the use of adaptive notation where the actual value governs if the value should be furnished as a JSON Number or embedded in a JSON String.

Other camps claim that consistent notation embedding values in JSON Strings would be more useful, albeit at the cost of always requiring two additional bytes.

WDYT?

Anders

# Hikaru Nakashima (6 years ago)

Is it better to be able to pass the option object as the second argument like this?

let option = { number: BigInt, reviver: conversion_function }
JSON.parse( json_string, option )

All JSON numbers are interpreted as follows

option.number( number_string )
# Anders Rundgren (6 years ago)

On 2018-05-19 14:48, Hikaru Nakashima wrote:

Is it better to be able to pass the option object as the second argument like this?

let option = { number: BigInt, reviver: conversion_function }
JSON.parse( json_string, option )

All JSON numbers are interpreted as follows

option.number( number_string )

Dear Nakashima-San,

Does this code permit parsing JSON data like the following?

{ "BigInt": 465456456465465465465465464646 }

AFAIK (I could indeed be wrong), the reviver function is called after parsing which is too late because then the value has already been stored/crippled/truncated into a JS Number object.

# Hikaru Nakashima (6 years ago)

I would like to be called and interpreted like BigInt("465456456465465465465465464646") when first parsing the numeric string.

This means that all numerical values passed to the reviver function and all numerical values contained in the post-analysis object are BigInt.

# Anders Rundgren (6 years ago)

On 2018-05-20 05:25, Hikaru Nakashima wrote:

I would like to be called and interpreted like BigInt("465456456465465465465465464646") when first parsing the numeric string.

This means that all numerical values passed to the reviver function and all numerical values contained in the post-analysis object are BigInt.

Doesn't this require a modified JSON.parse() to work?

If that's not the case, please provide a complete example.

Anders

# Hikaru Nakashima (6 years ago)

Sorry for lack of words. What I am talking about is a new proposal to modify JSON.parse().

# J Decker (6 years ago)

On Sat, May 19, 2018 at 8:48 PM, Hikaru Nakashima <oao.hikaru.oao at gmail.com>

wrote:

Sorry for lack of words. What I am talking about is a new proposal to modify JSON.parse().

There is json5 (json5.org; github.com/json5/json5;, npmjs.com/package/json5)

or I would entertain such things for json6... There is json5 (github.com/d3x0r/json6;, npmjs.com/package/json-6)

I would propose an addtional parameter passed to the reviver callback that is the original string value read from the JSON.

# Anders Rundgren (6 years ago)

On 2018-05-20 05:48, Hikaru Nakashima wrote:

Sorry for lack of words. What I am talking about is a new proposal to modify JSON.parse().

Then I understand :-)

I'm not entirely convinced that this is a workable approach because it breaks if you don't use a reviver but I leave that to the ES gurus to think about.

My question was really how non-ES systems preferable should "talk numbers" to ES when using JSON: esdiscuss/2018-May/050889

Anders

# Richard Gibson (6 years ago)

That seems like a question best addressed by something like JSON Schema. ECMAScript is not unique in lacking sufficient native machinery to process JSON numbers that have no IEEE 754 64-bit representation, and similar issues exist for binary data and complex types like date/time values.

# kai zhu (6 years ago)

fyi, there was extensive discussion on whether you can JSON.stringify BigInt, in the BigInt proposal [1]. the consensus is that you cannot [2]:

Here's tc39.github.io/proposal-bigint/#sec-serializejsonproperty the relevant JSON spec and here's tc39.github.io/proposal-bigint/#sec-tostring-applied-to-the-bigint-type the relevant String spec. Reading them, they say that JSON.stringify(1234n) throws (as discussed previously tc39/proposal-bigint#24) and String(1234n) gives "1234".

[1] github issue - Support JSON serialisation of BigInt values #24 tc39/proposal-bigint#24, tc39/proposal-bigint#24

[2] github issue - spec and README.md are unclear what serialized form of BigInt looks like using .toJSON / .toString tc39/proposal-bigint#124, tc39/proposal-bigint#124

kai zhu kaizhu256 at gmail.com

# kai zhu (6 years ago)

slightly off-topic, but this would be relevant for nodejs database-driver authors contemplating BigInt support.

here's the the tentative roadmap for indexeddb support for bigint [1]:

Design decisions:

BigInts compare greater than Number and less than everything else No type coercion between BigInt and Number; they are simply distinct, unrelated keys, even if mathematically equal No BigInt autoIncrement support--53 bits should be enough for anyone BigInts and BigInt wrappers are proposed to be made serializable, and therefore available as IndexedDB values, in whatwg/html#3480 whatwg/html#3480

Addresses #230 w3c/IndexedDB#230

[1] github pull-request - Allow BigInts as IndexedDB keys #231 w3c/IndexedDB#231, w3c/IndexedDB#231