Know this limitation before using JS everywhere
The Comedy of Numbers in JavaScript
Welcome, fellow web developers, to the delightful realm of JavaScript, where numbers dance on the thin line between precision and unpredictability.
In this whimsical yet educational journey, we'll embark on a quest to understand the peculiarities of JavaScript number precision and JSON serialization.
Inspiration is...
The Marvels of JavaScript Numbers
Let's kick things off with how JavaScript juggles numbers. Imagine our numbers as tightrope walkers, attempting daring feats within the confines of a 64-bit double-precision floating-point format.
Often, we walk with a safety net. Read along.
The Safety Range
2^53 (9007199254740992) is the upper limit of the safety range.
const largeInteger = 9007199254740992;
const jsonString = JSON.stringify({ value: largeInteger });
The Edge of Precision: Where Numbers Take the Plunge
Ah, but what happens when our daring numbers decide to push the limits?
const largerInteger = 9007199254740993;
const jsonString2 = JSON.stringify({ value: largerInteger });
As you noticed, the value is indifferent. The reason is the inconsistent floating number. Unlike C the value does not roll over, rather cap at the safety range.
The internal working is not jarring calculus, rather boring bit shifts, so I do not go over that; if you want, let me know in the comments, and I will reply with the details.
Strings to the Rescue: Precision in a Different Act
In this section, we introduce a clever workaround—representing large integers as strings. It's a performance unlike any other, where strings gracefully sidestep the pitfalls of precision loss.
const largeIntegerAsString = "9007199254740993000";
const jsonString3 = JSON.stringify({ value: largeIntegerAsString });
Strings take center stage, demonstrating how they elegantly handle large integers without compromising precision (sacrificing performance and storage).
Should you note that the problem arises when transmitting the data across networks with different endiness!
To mitigate this, I suggest you use strings as a primitive method. Looking for a more elegant solution?
BigInt
In the vast world of JavaScript precision, BigInt emerges as the hero, addressing the challenges posed by colossal integers.
BigInt
is created by either appending n
suffix, or using BigInt()
constructor.
Unlike traditional numbers, BigInt gracefully handles integers of any size, breaking free from the constraints of the safe integer range. On top of this, all the arithmetic operations are compatible as well.
// BigInt
const largeInteger = BigInt("9007199254740992000123456789");
console.log(largeInteger); // gives 9007199254740992000123456789n
// BigInt arithmetic
const result = largeInteger + BigInt(42);
console.log(result); // gives 9007199254740992000123456831n
BigInt
plays well with regular integers as well.
// BigInt comparison
const isGreaterThanRegular = largeInteger > regularNumber;
console.log(isGreaterThanRegular); // gives true
If you're a curious beginner or a seasoned developer, BigInt offers a reliable ally, reshaping the narrative of numeric precision in JavaScript.
There's a catch though. BigInt
is a modern ECMAScript.
Workaround
You may use a third-party library as polyfill or fallback called bignumber.js
In closing, mastering JavaScript number precision is key for every developer. Whether you're starting out or a seasoned pro, understanding these intricacies is crucial. For more insights and exclusive content, subscribe(it's free) and support my college degree.
Stay ahead in the world of web development—subscribe now! 🚀
Till then it's meTheBE signing off, Bye.