2012-07-14 85 views
0

我正在写一个应该做权力的函数,但只显示指定的最后n位数。它的工作很棒......主要是。由于某些原因,当我指定了我想要的最后几位数字时,它一直工作到包括数字12在内.12以上的任何数字似乎给我一个非常奇怪的数字。我知道我必须错过一些明显的东西,但我真的没有看到它。获取大数的最后13位数

下面是代码:

function power(base, exponent, digits) { 
total = base; 
for(i = 1; i < exponent; i++) { 
    total = total * base; 

    if(total.toString().length > digits) { 
     total = total.toString().substr(total.toString().length - digits, digits); 
     } 
    } 

return total; 
} 

所以,对于一些例子(显示12个数字,下正常工作):

如果我做电力(999,999,1)我结束了=> 9

如果我做电源(999,999,5)我最终=> 98999

如果我做电源(999,999,12)我最终=> 000499998999

这里是它开始搞乱:

如果我做电源(999,999,13)我最终=> 5710054009000

如果我做电源(999,999,14)余结束'='79077027006000'

起初我以为我打了某种整数限制和科学记数法是搞砸了,但我不认为是这样,因为它应该工作到20位数字。

我怀疑这是我在减少if语句中的字符串的方式有问题。但我不确定为什么它不会搞乱13位数以下的计算。

谢谢!

+3

你知道IEEE 794浮点是如何工作的吗? – Pointy 2012-07-14 04:07:05

+0

我有一些想法。但我不认为它会失去13位数的精确度。我的功能背后的想法是永远不要让它与高数字一起工作。它从不乘以任何高于第13位的数字。 – renosis 2012-07-14 04:25:26

+6

@renosis 13位数字乘以3位数字是(最多)16位数字。双精度浮点数只能精确到15位数。 – 2012-07-14 05:57:10

回答

2

您需要一个函数来计算b^e(mod m)。一个好的算法被称为square and multiply

Algorithm PowerMod: Compute b^e (mod m) with b, e and m all positive integers. 
1. [Initialize] Set r := 1. 
2. [Terminate when finished] If e == 0, return r and stop. 
3. [Multiply if odd] If e is odd, set r := r * b (mod n). 
4. [Square and iterate] Set e := floor(e/2). Set b := b * b (mod n). Go to Step 2. 

然后让你的计算,说PowerMod(999,999,10^14);你应该得到17000499998999.

+0

我试过了,我必须在这里丢失一些东西。这不会给20位数以上的值。我只是将不得不将每一个计算转换为一个字符串,这个字符串可以用于我计算的每个地方,不是吗? – renosis 2012-07-19 01:40:12

+0

PowerMod算法是正确的。您需要一个大整数库,它不会限制您可以计算的整数范围。我不知道JavaScript,所以我不能告诉你是否内置了大整数,或者有可用的库提供大整数。 – user448810 2012-07-19 12:54:38