简体   繁体   English

创建JavaScript数学库的算法

[英]Arithmetics in Creation of a JavaScript Maths Lib

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. 我正在为JavaScript创建一个数学库,只是我想能够以字符串格式添加大数,因为JavaScript中的浮点不能永远保持不变,您最多只能添加一个最大值。 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 在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? "2524618239759212479135012" + "128590322830498023412234" = "2524618239759212479135012128590322830498023412234"当然不起作用,我希望能够通过算法使用数组或字符串来做到这一点?

I know easy how to put them up like: 我知道如何像这样放置它们:

  22
+ 23 
 ---
  55

But how am I going to implement that into my code? 但是我该如何在我的代码中实现呢?

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. 本质上,我们将乘法分解为3 * 45 + 20 * 45。 But we can go further and turn it into 3*5 + 20*5 + 3*40 + 20*40. 但是我们可以进一步将其变成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. 我会选择数字而不是字符串值,因为字符串太慢且含糊不清(“ 0” ==“ 00” ...),您将需要将其转换为数字。 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. 因此,3 + 20的等效值为3e0 + 2e1。 In binary, 23 is 10111, which could be 1e111 + 111e0 (1x2^5 + 7x2^0). 在二进制中,23是10111,可能是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. 在javascript中,无论如何,所有数字都作为IEEE-754双精度浮点数保存,因此您有52位的尾数和11位的指数。

Consider rewriting your large integer as binary, and putting 24 bits of it into each float; 考虑将大整数重写为二进制,然后将其24位放入每个float中; since the largest 24 bit integer is 2^23, you could fit (2^23)^2 into a single float (requiring 46 bits). 因为最大的24位整数是2 ^ 23,所以您可以将(2 ^ 23)^ 2放入单个float中(需要46位)。 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. 这将允许您一次执行24位乘法,并且每次乘法的结果都可以保证适合浮点变量。 You could then perform all the carry operations with some headroom (52-46=6 bits, => 2^5 = 1024). 然后,您可以以一定的余量(52-46 = 6位,=> 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. 要了解如何进行除法,请为一个大整数除法编写单元测试,这应该是有启发性的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM