Question

I am making a math lib for JavaScript, simply I want to be able to add big numbers, in string format since the floating point in JavaScript can't hold forever, you can only add up to a max value. So I think about making the numbers in strings and then calculate them by hand like:

2524618239759212479135012 + 128590322830498023412234 = 2653208562589710502547246

In JS: 2524618239759212479135012 + 128590322830498023412234 = 2.6532085625897103e+24

So I want to do it like this:

function Add(strA, strB) {
  // How am I going to calculate it?
}

"2524618239759212479135012" + "128590322830498023412234" = "2524618239759212479135012128590322830498023412234" Which certainly do not work, I want to be able to do that with an algorithm, using arrays or strings?

I know easy how to put them up like:

  22
+ 23 
 ---
  55

But how am I going to implement that into my code?

Was it helpful?

Solution

Start with some tests.

You will need to multiply and divide some large numbers to create some test cases for your large integer library. The process of doing that will be a good start for seeing how the code might work on the numbers.

Consider multiplication:

  23
x 45
----
 115
+920
----
1035

Essentially we are splitting the multiplication up into 3*45 + 20*45. But we can go further and turn it into 3*5 + 20*5 + 3*40 + 20*40. This way would be more like a vector dot product:

| 3|   | 5|
|20| . |40|

The point is that you can decompose a given operation into a series of smaller operations whose results you combine to reach the final value.

I would opt for numeric rather than string values, as strings are slow and ambiguous ("0" == "00" ...) and you will need to convert to numbers somewhere along the line. Consider constructing each number from a series of floating point numbers; the exponent will hold the scale information and the mantissa holds the number. Thus the equivalent of 3 + 20 is 3e0 + 2e1. In binary, 23 is 10111, which could be 1e111 + 111e0 (1x2^5 + 7x2^0). In javascript all numbers are held as IEEE-754 double precision floats anyway, so you have 52 bits of mantissa and 11 bits of exponent.

Consider rewriting your large integer as binary, and putting 24 bits of it into each float; since the largest 24 bit integer is 2^23, you could fit (2^23)^2 into a single float (requiring 46 bits). That would permit you to perform a multiplication 24 bits at a time and the result of each multiplication would be guaranteed to fit into a floating point variable. You could then perform all the carry operations with some headroom (52-46=6 bits, => 2^5 = 1024). Storage of a large integer would then be just an array of numbers, and you could do addition and multiplication without much effort.

To understand how to do the division, write the unit test for a large integer division, and it should be instructive.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top