1

I got a number 1267508826984464384 from json response. Here i print the number.

<script>
var num = 1267508826984464384;
console.log(num);

var num = "1267508826984464384";
console.log(num);
</script>

output is

enter image description here

In the first print the output is different from the original value. I need the same value as given. Is it possible?

Pamba
  • 776
  • 1
  • 16
  • 29
  • 1
    That number is bigger than `Number.MAX_SAFE_INTEGER` so it has lost its precision – Hao Wu Jun 05 '20 at 04:56
  • https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/MAX_SAFE_INTEGER – kyun Jun 05 '20 at 04:56
  • Does this answer your question? [node.js is there any proper way to parse JSON with large numbers? (long, bigint, int64)](https://stackoverflow.com/questions/18755125/node-js-is-there-any-proper-way-to-parse-json-with-large-numbers-long-bigint) – user120242 Jun 05 '20 at 05:00

4 Answers4

2

JavaScript uses floating point under the hood to store numbers. Floating point double precision, which is what JavaScript uses, can only store 64 bits of data. With the way numbers are represented in this manner, this means that there's a limit to how big a Number can normally be (2^53 - 1 for double precision floating point). Your number in the example has gone over this limit (overflow) and hence is being rounded by JavaScript.

You can use BigInt:

var num = BigInt(1267508826984464384);
console.log(num); // logs 1267508826984464384n, with n representing that it's a BigInt type

var num = "1267508826984464384";
console.log(num); // logs 1267508826984464384

May be helpful to read What Every Programmer Should Know About Floating-Point Arithmetic for more information on why this is the case.

rb612
  • 5,280
  • 3
  • 30
  • 68
1

They are different types (int and string, respectfully). What you are seeing in the top example is integer overflow (safely abstracted by JS). You can use a big integer to bypass this issue

const hugeString = BigInt("1267508826984464384")

console.log(hugeString + 1n)  // 1267508826984464385n

The type of this is BitInt and it will safely allow you to represent your number as a integer. This type must be treated different and the additions must also be BigInt (as shown in the example above).

justahuman
  • 607
  • 4
  • 13
1

BigInt is a built-in object that provides a way to represent whole numbers larger than 253 - 1, which is the largest number JavaScript can reliably represent with the Number primitive and represented by the Number.MAX_SAFE_INTEGER constant. BigInt can be used for arbitrarily large integers.

From MDN. You can use it like so:

const theBiggestInt = 9007199254740991n

const alsoHuge = BigInt(9007199254740991)
// ↪ 9007199254740991n

const hugeString = BigInt("9007199254740991")
// ↪ 9007199254740991n

const hugeHex = BigInt("0x1fffffffffffff")
// ↪ 9007199254740991n

const hugeBin = BigInt("0b11111111111111111111111111111111111111111111111111111")
// ↪ 9007199254740991n
Isaac Corbrey
  • 553
  • 3
  • 20
0

RegEx for finding numbers and quoting them. Looks for prop value boundaries and a sequence of digits and optionally one period, and replaces inserting with quotes around the number value.

RegEx should be adjusted for maximum length or tolerances for numbers to be quoted as strings.
key or value prefix/suffix can be added, so that a JSON.parse reviver function can recognize them and parse to big.js or BigInt.

In most cases, you probably already know if you might receive a large number, and could probably just use a trivial RegEx replace on the specific property you need.
And, you should be coordinating with the server-side to give the data to you in another form that is safe to consume.

Parsing number strings using BigInt and big.js.

str = String.raw `{"j\"son":1234561251261262131231231231231231231231231232123123123,
"array":
[123123123124124214124124124124.111,
124124124124124124124124124,
124124124124124124124124
]}
`
str = str.replace(/((?:{|,|\[)\s*(?:"(?:[^"]|\\")+"\s*:\s*)?)(\d+\.?\d*)(\s*)(?=,|}|\])/g, `$1"$2"$3`)
// note: capture group $3 is just whitespace, which can normally be ignored; included to be "technically accurate"

console.log(
  str,
  (BigInt(JSON.parse(str)[`j"son`]) + 1n).toString(),
  (Big(JSON.parse(str).array[0]).plus(0.0003)).toFixed()
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/big.js/5.2.2/big.min.js" integrity="sha256-gPNmhPlEOUlyAZomtrYRW/HSIjBOOl2LVxft3rsJpxI=" crossorigin="anonymous"></script>
user120242
  • 14,918
  • 3
  • 38
  • 52