Hal Friday

Posted on

# YES.

Had to dig through quite a few articles to get a simple answer to this one, so I figured I'd put it right at the beginning. Yes, regular math calculations using BigInt cost more for the computer to execute than if you were just using Numbers.

JavaScript, like any programming language, is made up of a bunch of different types -- I went into a little depth on the topic of types in this blog post over here. Two of those types are "BigInt" and "Number". So first off, we'll give a clear picture of both:

### NUMBER

• Primitive (meaning they cannot be changed no matter what)
• 64-bit (meaning there is a size limit)
• Imprecise at a point (meaning if a calculation gets past 17 decimal points, JavaScript will stop math-ing and round the number)
• Is always a float (meaning 17.0 === 17 returns true)

And just for fun, here are some examples of numbers.

• 17
• 1234.123123123123
• NaN
• Infinity

There are those who think it's weird that NaN, standing for Not-A-Number, is of type Number -- but honestly, it provides more detail about itself as an error if it's still associated with Number.

### BIGINT

Large, hefty numbers. Could eat your grandad's numbers for breakfast. Here are some BigInt facts:

• Also Primitive
• Represents anything beyond the 64-bit limit (which can be checked for using JavaScript's method Number.MAX_SAFE_INTEGER)
• Does not like to mix with numbers (10 * BigInt(10) will result in a type error)
• Does somewhat mix with Strings
• Puts a fancy little n at the end of the number

It's helpful to play around with BigInts to get a feel for them. In whatever JavaScript environment you're used to, you can get your computer to print out some BigInts with the following:

• BigInt("32787835783895638958923489124891234")
• note that the BigInt method here will accept a string
• BigInt(5)
• 1n

## So, why is BigInt math more expensive than Number math?

Your intuition probably led you to this already, but there is the one obvious thing: BigInts are bigger. Not in the way that 100 is bigger than 10, but in the way that your computer receives and handles the BigInt data type. The memory set aside for a BigInt is always larger than a regular Number, regardless of the value of the BigInt itself. So, if you have two variables:

let optionA = 15
let optionB = 15n

Both are 15, but optionB is clunkier. Thicker. BigInter.

A side note on equality:
JavaScript does recognize that optionA and optionB are equal to 15, but a strict equality operator will return false because of their differing types. If you need to compare between BigInts and Numbers, you should use loose equality (==).

The other reason BigInt calculations take more time & space is that the instructions for handling these calculations are in the software of JavaScript. When you do a Math calculation like 10*81, your computer uses its hardware, which is easily accessible and requires almost no searching or computational power. When you try something special like 10n * 81n, it has to go and find the BigInt JavaScript functions, feed your input in, and calculate the result at a high level. You can read more about that from this TekTutorialsHub post.

You can prove this by benchmarking JavaScript methods using both types of math. Check out this Repl.it and hit Run to see it in action.

## What's the practical use of knowing this?

The only reason I went down this rabbit hole was for interview prep: practicing algorithms. There is an interesting LeetCode problem (found here) which asks you to add two linked lists together and return their sum as a linked list. After solving the initial prompt, my code was still failing because some of the test cases resulted in massive....some might say BigInt numbers.

To resolve this problem, my first instinct was, "Well, what if we treat every single number like it's gonna be a BigInt?" And the answer to that question is that the solution will pass, but it will be slower than a...car that's slow...or...whatever, it'll make your algorithm super slow. So you really need to allow for and handle BigInts separately, giving them the attention they deserve as unique circumstances.

Interview prep is a huge practical reality for software engineers of all levels, but there are also real-world applications for BigInts, such as massive database management, precise math with large numbers for financial applications, high-accuracy timestamps, and anything else people do with fancy and elaborate math. Who knows, maybe rocket science.

There is a lot more to the story with the BigInt datatype, but hopefully this gave a useful and concise introduction. Have fun & feel free to drop a comment with any additions, questions, or thoughts!

James Liu

Interesting.

Let's make this mental leap: They were keeping the numbers as linked lists because they overflowed safe-ints.

What would be better, maintaining a linked list math algorithms library inside your engineering team, or using bigints and having the V8 team maintain the bigint functionality for you?

Also, even if your algorithm is basically, try using number arithmetic, check if the result is of type int, if not, try again using BigInt, is that worthwhile keeping in your code instead of keeping BigInts natively? What is the cost of converting the numbers back and forth between the linked list and the number types?

Also, how are we persisting these numbers to disk? I don't think databases generally support integers larger than 64 bits.

And, supposing you decided to switch. How do you weigh the pros and cons of refactoring to bigints?

Hal Friday

Interesting thoughts, thanks for the comment! As for your first question, whether keeping a linked-list library would be better than using V8 — it would be tough to gauge, as I think it depends on how frequently your library is used, how efficiently the methods run, and the intent behind creating the library in the first place: will it be purely internal? Will the company publish it as open source down the line? There are a lot of unknowns there. Instinctively, I would lean towards using V8 because they have had years to test and improve on software which solves specifically this type of problem.
With that said, I think the cost of conversion from lists to numbers (to possibly BigInts) and back to lists is pretty high, especially if we assume this process would happen thousands of times a day.
If tasked with persisting the numbers to the disk, I would store them as Strings, one and all, the way JSON does — that way we don’t need to deal with whether or not they are BigInts unless they are being used in the functional side of the app.
Overall, your questions really bring to light the fact that the problem as posed to me didn’t contain enough detail to tell whether using BigInts could be considered “worth it” or not. I think it would be a situational answer, which would need hard data like type & frequency of requests to really make a call.