Big integer, Big float, and operator overloading ideas

Anders Rundgren anders.rundgren.net at gmail.com
Tue May 29 14:33:58 UTC 2018


On 2018-05-29 10:32, kai zhu wrote:
> @anders, i'm just brainstorming if JSON could meet most of industry-needs for large-numbers (with minimal changes), if
> 
> 1. JSON.stringify was enhanced to stringify fixed-precision BigInt64 and BigDecimal128 as strings (including suffix to make userland parsing easier)
> 
> 2. JSON.parse is left untouched
> 
> ```js
> state = {
>      "bigInt64": -9223372036854775807n,
>      "bigDecimal128": -9.99999999999999999999999999999999e6144dd
> }
> 
> // JSON.stringify will stringify BigInt64 and BigDecimal128 as strings
> JSON.stringify(state) = '{\
>      "bigInt64": "-9223372036854775807n",\
>      "bigDecimal128": "-9.99999999999999999999999999999999e6144dd"\
> }'
> 
> // JSON.parse will NOT un-stringify BigInt64 and BigDecimal128 (userland responsibility)
> JSON.parse(JSON.stringify(state)) = {
>      "bigInt64": "-9223372036854775807n",
>      "bigDecimal128": "-9.99999999999999999999999999999999e6144dd"
> }
> ```

This is exactly what I'm hoping on.  Unfortunately there's no community dealing with big numbers in JSON.
Microsoft's solution for .NET and Oracle's for Java have nothing in common and the OpenAPI/Swagger folks run their show as well.

It is really entirely in "userland" = do whatever works for you :-)

Anders

> 
>> On 29 May 2018, at 12:22 PM, Anders Rundgren <anders.rundgren.net at gmail.com <mailto:anders.rundgren.net at gmail.com>> wrote:
>>
>> On 2018-05-28 21:05, Fabrice Bellard wrote:
>>> Hi,
>>> JSON.stringify is currently fully compatible with the TC39 BigInt
>>> proposal, so it throws an exception in the case of a bigint value. You
>>> can add:
>>
>> I haven't looked into the BigInt proposal but if it breaks I-JSON/JSON.parse()
>> I would vote against it.
>>
>> The JSON community is unfortunately already pretty confused and divided:
>> https://github.com/cyberphone/I-JSON-Number-System#existing-solutions
>>
>> Microsoft's JSON/.NET guru's view on JSON.parse():
>> https://github.com/JamesNK/Newtonsoft.Json/issues/1706#issuecomment-390514965
>>
>> Anders
>>
>>> BigInt.prototype.toJSON = function() { return this.toString(); }
>>> to handle this case. It could also be possible to modify the behavior of
>>> JSON.stringify in bigint mode so that it does not throw an exception in
>>> case of a bigint value.
>>> Regarding the unresponsive cases you noticed with large exponents in
>>> floating point literals, it is a known problem of the current code which
>>> will be corrected.
>>> Best regards,
>>> Fabrice.
>>> On 05/28/2018 07:43 PM, kai zhu wrote:
>>>> hi fabrice, what you’ve done is interesting and impressive;  but an
>>>> integration-level concern (if tc39 is to consider standardizing your
>>>> extension, rather than keep it userland) is how would a web-project go
>>>> about baton-passing these arbitrary-precision numbers between browser
>>>> <-> server <-> persistent-storage via JSON?  what would happen if you
>>>> pass an arbitrarily large float as a “number” type to current mysql (or
>>>> native-module sqlite3) driver?
>>>>
>>>> playing with your live web-demo @ http://numcalc.com/, it seems
>>>> JSON.stringify has divergent behavior between math-equivalent large
>>>> floats (preserves full-precision) and large integers (throws error as a
>>>> bigint):
>>>>
>>>> ```js
>>>> mjs > 12345678901234567890.0e0 === 12345678901234567890
>>>> true
>>>>
>>>> mjs > typeof 12345678901234567890.0e0
>>>> "number"
>>>> mjs > JSON.stringify(12345678901234567890.0e0)
>>>> "12345678901234567890”
>>>>
>>>> mjs > typeof 12345678901234567890
>>>> "bigint"
>>>> mjs > JSON.stringify(12345678901234567890)
>>>> TypeError: bigint are forbidden in JSON.stringify
>>>>     at to_str (stdlib.js)
>>>>     at stringify (stdlib.js)
>>>>     at <eval> (<evalScript>)
>>>>     at evalScript (native)
>>>>     at eval_and_print (repl.js)
>>>>     at setPrec (native)
>>>>     at handle_cmd (repl.js)
>>>>     at readline_handle_cmd (repl.js)
>>>>     at handle_key (repl.js)
>>>>     at handle_char (repl.js)
>>>>     at handle_byte (repl.js)
>>>>
>>>> mjs > JSON.parse(JSON.stringify(1.12345678901234567890123456789e123456))
>>>> 1.12345678901234567890123456789e+123456 // takes ~200ms to process
>>>>
>>>> mjs > JSON.parse(JSON.stringify(1.12345678901234567890123456789e-123456))
>>>> 1.12345678901234567890123456789e-123456 // takes ~200ms to process
>>>>
>>>> mjs > JSON.stringify(1.1e1234567890) // unresponsive
>>>>
>>>> mjs > JSON.stringify(1.1e-1234567890) // unresponsive
>>>> ```
>>>>
>>>> kai zhu
>>>> kaizhu256 at gmail.com <mailto:kaizhu256 at gmail.com><mailto:kaizhu256 at gmail.com>
>>>>
>>>>
>>>>
>>>>> On 28 May 2018, at 7:25 PM, Fabrice Bellard <fabrice at bellard.org <mailto:fabrice at bellard.org>
>>>>> <mailto:fabrice at bellard.org>> wrote:
>>>>>
>>>>> A new revised version of the "BigNum extensions" is available at
>>>>> http://numcalc.com/jsbignum.pdf . This new version is 100% compatible
>>>>> with standard Javascript with the addition of a "use bigint" mode. It
>>>>> is split into 4 proposals:
>>>>>
>>>>> 1) Overloading of the standard operators to support new types such as
>>>>> complex numbers, fractions or matrixes.
>>>>>
>>>>> 2) Bigint mode where arbitrarily large integers are available by
>>>>> default (no "n" suffix is necessary as in the BigInt proposal at
>>>>> https://tc39.github.io/proposal-bigint/ ).
>>>>>
>>>>> 3) Arbitrarily large floating point numbers in base 2 using the IEEE
>>>>> 754 semantics.
>>>>>
>>>>> 4) Optional "math" mode which modifies the semantics of the division,
>>>>> modulo and power operator. The division and power operator return a
>>>>> fraction with integer operands and the modulo operator is defined as
>>>>> the Euclidian remainder.
>>>>>
>>>>> A complete demo is available at http://numcalc.com . The command
>>>>> "\mode [std|bigint|math]" can be used to switch between the standard
>>>>> javascript mode, bigint mode or math mode. In standard Javascript
>>>>> mode, the complete TC39 BigInt proposal is supported. In the demo, the
>>>>> default
>>>>> floating point precision is set to 128 bits. It can be set back to the
>>>>> default Javascript precision with "\p f64" or "\p 53 11".
>>>>>
>>>>> Fabrice.
>>>>> _______________________________________________
>>>>> es-discuss mailing list
>>>>> es-discuss at mozilla.org <mailto:es-discuss at mozilla.org><mailto:es-discuss at mozilla.org>
>>>>> https://mail.mozilla.org/listinfo/es-discuss
>>>>
>>> _______________________________________________
>>> es-discuss mailing list
>>> es-discuss at mozilla.org <mailto:es-discuss at mozilla.org>
>>> https://mail.mozilla.org/listinfo/es-discuss
> 



More information about the es-discuss mailing list