Reputation: 822
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
In the first print the output is different from the original value. I need the same value as given. Is it possible?
Upvotes: 1
Views: 408
Reputation: 15268
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>
Upvotes: 0
Reputation: 5563
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.
Upvotes: 2
Reputation: 593
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
Upvotes: 1
Reputation: 637
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).
Upvotes: 1