只需要前k位数时的快速取幂?

时间:2009-03-11 15:56:01

标签: math exponentiation

这实际上是为了编程比赛,但我已经非常努力,甚至没有得到最微弱的线索如何做到这一点。

找出n m 的第一个和最后一个k位数,其中n和m可以非常大~10 ^ 9.

对于最后的k位数,我实现了模幂运算。

对于第一个k,我想到使用二项式定理达到某些幂,但这涉及到因子的大量计算,我不知道如何找到n ^ m可以扩展为的最佳点(x + Y)

那么有没有已知的方法来查找前k个数字而不执行整个计算?

更新 1< = k< = 9且k总是< = n m中的数字

4 个答案:

答案 0 :(得分:4)

不确定,但身份n m = exp10(m log10(n))= exp(q(m log(n)/ q))其中q = log(10)来到请注意,exp10(x)的前K个数字= exp10的前K个数字(frac(x)),其中frac(x)= x = x - floor(x)的小数部分。

更明确:n m 的前K个数字是其mantissa = exp(frac(m log(n)/ q)* q的前K个数字) ,其中q = log(10)。

或者你甚至可以在这个会计练习中更进一步,并使用exp((frac(m log(n)/ q)-0.5)* q)* sqrt(10),它也具有相同的尾数(+因此相同的前K个数字),以便exp()函数的参数以0为中心(在+/- 0.5 log 10 = 1.151之间),以便快速收敛。

(一些例子:假设你想要2 100 的前5位数。这等于exp的前5位数((frac(100 log(2)/ q)-0.5)* q )* sqrt(10)= 1.267650600228226。根据MATLAB,2 100 的实际值是1.267650600228229e + 030,我没有方便的bignum库。尾数为2 1,000,000,000 我得到了4.612976044195602但是我真的没有办法检查...... Mersenne primes上有一个页面,其中某人已经完成了艰苦的工作; 2 20996011 -1 = 125,976,895,450 ...我的公式给出了在MATLAB中计算的1.259768950493908,它在第9位后失败。)

我可能会使用Taylor series(对于exp 和log ,而不是n m )及其错误界限,并继续添加术语,直到错误界限低于前K个数字。 (通常我不使用泰勒级数进行函数逼近 - 它们的误差被优化为在单个点附近最精确,而不是超过期望的间隔 - 但它们的优势在于它们在数学上很简单,而且你只需添加附加术语即可将精度提高到任意精度。

对于对数,我会使用你最喜欢的近似值。

答案 1 :(得分:2)

好。我们想要计算alt text并且只获得 n 的第一个数字。

通过以下迭代计算alt text

alt text

你有alt text。 不完全计算每个alt text。 问题是alt text的相对误差较小 比 n 乘以 a 的相对误差。

您希望最终相对误差小于alt text。 因此,每个步骤的相对误差可能是alt text。 删除每一步的最后一位数字。

例如,a = 2,b = 16,n = 1。最终相对误差为10 ^ { - n} = 0,1。 每个步骤的相对误差是0,1 / 16> 0.001。 因此,每个步骤的3个数字很重要。 如果n = 2,则必须保存4位数。

2(1),4(2),8(3),16(4),32(5),64(6),128(7),256(8),512(9),1024( 10) - > 102, 204(11),408(12),816(13),1632(14) - > 163,326(15),652(16)。

答案:6。

此算法具有 O(b)的复杂性。但很容易改变它 O(log b)

答案 2 :(得分:0)

假设你在每一步截断?不确定这将是多么准确,但是,例如,采取 N = 11 m =一些大数字 你想要前2位数。

递归:

  1. 11 x 11 - > 121,truncate - > 12(1截断或舍入) 然后取截断值并再次提升
  2. 12 x 11 - > 132 truncate - > 13 重复,

  3. (132截断)×11 - > 143。 ...

  4. 最后添加#0相当于你已完成的截断数。

答案 3 :(得分:0)

你看过exponentiation by squaring了吗?您可以修改其中一种方法,以便只计算必要的内容。

在我上一次的算法课上,我们必须实现类似于你正在做的事情,我依旧记得这个页面很有用。