diff --git a/README.md b/README.md index 86378cb..06d3dec 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,9 @@ json-bigint [![Build Status](https://secure.travis-ci.org/sidorares/json-bigint.png)](http://travis-ci.org/sidorares/json-bigint) [![NPM](https://nodei.co/npm/json-bigint.png?downloads=true&stars=true)](https://nodei.co/npm/json-bigint/) -JSON.parse/stringify with bigints support. Based on Douglas Crockford [JSON.js](https://github.com/douglascrockford/JSON-js) package and [bignumber.js](https://github.com/MikeMcl/bignumber.js) library. Native Bigint was added to JS recently, so we added an option to leverage it. However, the parsing with native BigInt is kept an option for backward compability. +JSON.parse/stringify with bigints support. Based on Douglas Crockford [JSON.js](https://github.com/douglascrockford/JSON-js) package and [bignumber.js](https://github.com/MikeMcl/bignumber.js) library. + +Native `Bigint` was added to JS recently, so we added an option to leverage it instead of `bignumber.js`. However, the parsing with native `BigInt` is kept an option for backward compability. While most JSON parsers assume numeric values have same precision restrictions as IEEE 754 double, JSON specification _does not_ say anything about number precision. Any floating point number in decimal (optionally scientific) notation is valid JSON value. It's a good idea to serialize values which might fall out of IEEE 754 integer precision as strings in your JSON api, but `{ "value" : 9223372036854775807}`, for example, is still a valid RFC4627 JSON string, and in most JS runtimes the result of `JSON.parse` is this object: `{ value: 9223372036854776000 }` @@ -107,40 +109,83 @@ Default type: object, With option type: string ``` -#### options.alwaysBigNumber, boolean, default false -Specifies if all numbers should be stored as BigNumber/BigInt. +#### options.useNativeBigInt, boolean, default false +Specifies if parser uses native BigInt instead of bignumber.js -Note that this is a dangerous behavior as it breaks the default functionality of being able to convert back-and-forth without data type changes (as this will convert all Number to be-and-stay BigNumber/BigInt) +example: +```js +var JSONbig = require('json-bigint'); +var JSONbigNative = require('json-bigint')({"useNativeBigInt": true}); +var key = '{ "key": 993143214321423154315154321 }'; +console.log(`\n\nStoring the Number as native BigInt, instead of a BigNumber`); +console.log('Input:', key); +var normal = JSONbig.parse(key); +var nativeBigInt = JSONbigNative.parse(key); +console.log('Default type: %s, With option type: %s', typeof normal.key, typeof nativeBigInt.key); -#### options.useBigInt, boolean, default false -Specifies if parser uses native BigInt instead of bignumber.js +``` -### Links: -- [RFC4627: The application/json Media Type for JavaScript Object Notation (JSON)](http://www.ietf.org/rfc/rfc4627.txt) -- [Re: \[Json\] Limitations on number size?](http://www.ietf.org/mail-archive/web/json/current/msg00297.html) -- [Is there any proper way to parse JSON with large numbers? (long, bigint, int64)](http://stackoverflow.com/questions/18755125/node-js-is-there-any-proper-way-to-parse-json-with-large-numbers-long-bigint) -- [What is JavaScript's Max Int? What's the highest Integer value a Number can go to without losing precision?](http://stackoverflow.com/questions/307179/what-is-javascripts-max-int-whats-the-highest-integer-value-a-number-can-go-t) -- [Large numbers erroneously rounded in Javascript](http://stackoverflow.com/questions/1379934/large-numbers-erroneously-rounded-in-javascript) +Output +``` +Storing the Number as native BigInt, instead of a BigNumber +Input: { "key": 993143214321423154315154321 } +Default type: object, With option type: bigint -### Native BigInt support +``` -#### Stringifying -Full support out-of-the-box, stringifies BigInts as pure numbers (no quotes, no `n`). +#### options.alwaysParseAsBig, boolean, default false +Specifies if all numbers should be stored as BigNumber. + +Note that this is a dangerous behavior as it breaks the default functionality of being able to convert back-and-forth without data type changes (as this will convert all Number to be-and-stay BigNumber) -#### Parsing +example: ```js -var JSONbig = require('json-bigint')({"useNativeBigInt": true}); +var JSONbig = require('json-bigint'); +var JSONbigAlways = require('json-bigint')({"alwaysParseAsBig": true}); +var key = '{ "key": 123 }'; // there is no need for BigNumber by default, but we're forcing it +console.log(`\n\nStoring the Number as a BigNumber, instead of a Number`); +console.log('Input:', key); +var normal = JSONbig.parse(key); +var always = JSONbigAlways.parse(key); +console.log('Default type: %s, With option type: %s', typeof normal.key, typeof always.key); + ``` -If you want to force all numbers to be parsed as `bignumber.js` -```js -var JSONbig = require('json-bigint')({"alwaysParseAsBig": true}); + +Output +``` +Storing the Number as a BigNumber, instead of a Number +Input: { "key": 123 } +Default type: number, With option type: object + ``` -If you want to force all numbers to be parsed as `BigInt`s + +If you want to force all numbers to be parsed as native `BigInt` (you probably do! Otherwise any calulations become a real headache): ```js var JSONbig = require('json-bigint')({"alwaysParseAsBig": true, "useNativeBigInt": true}); ``` +### Links: +- [RFC4627: The application/json Media Type for JavaScript Object Notation (JSON)](http://www.ietf.org/rfc/rfc4627.txt) +- [Re: \[Json\] Limitations on number size?](http://www.ietf.org/mail-archive/web/json/current/msg00297.html) +- [Is there any proper way to parse JSON with large numbers? (long, bigint, int64)](http://stackoverflow.com/questions/18755125/node-js-is-there-any-proper-way-to-parse-json-with-large-numbers-long-bigint) +- [What is JavaScript's Max Int? What's the highest Integer value a Number can go to without losing precision?](http://stackoverflow.com/questions/307179/what-is-javascripts-max-int-whats-the-highest-integer-value-a-number-can-go-t) +- [Large numbers erroneously rounded in Javascript](http://stackoverflow.com/questions/1379934/large-numbers-erroneously-rounded-in-javascript) + +### Note on native BigInt support + +#### Stringifying +Full support out-of-the-box, stringifies BigInts as pure numbers (no quotes, no `n`) + #### Limitations -Currently `s === JSONbig.stringify(JSONbig.parse(s))` but `o !== JSONbig.parse(JSONbig.stringify(o))` when `o` has value of something like `123n`, `JSONbig` stringify this as `123`, which becomes `number` when being reparsed. -There is currently no consistent way to deal with this issue, so we decided to leave it this way, handling this specific case is then up to users. \ No newline at end of file +- Roundtrip operations + +`s === JSONbig.stringify(JSONbig.parse(s))` but + +`o !== JSONbig.parse(JSONbig.stringify(o))` + +when `o` has a value with something like `123n`. + +`JSONbig` stringify `123n` as `123`, which becomes `number` (aka `123` not `123n`) by default when being reparsed. + +There is currently no consistent way to deal with this issue, so we decided to leave it, handling this specific case is then up to users. \ No newline at end of file