【问题标题】:Power of two to get an integer2的幂得到一个整数
【发布时间】:2015-01-08 12:06:49
【问题描述】:

我需要一种(相当)快速的方法来为我的代码获取以下内容。 背景:我必须使用数字的幂及其乘积,所以我决定使用日志。 现在我需要一种将日志转换回整数的方法。

我不能只取 2^log_val(我正在使用 log base 2),因为答案会太大。事实上,我需要为给定的 M 给出答案 mod M。

我试过这样做。我将 log_val 写为 p+q,其中 q 是浮点数,q

这对我来说太长了,因为在最坏的情况下我会采取 O(p) 步骤。 有没有更好的办法?

【问题讨论】:

  • M 是固定的吗?根据您拥有的内存量和所需的精度,您可以将四舍五入的 2^q 值存储在预先计算的表格中。
  • 实际上没有,我有很多不同的 M。并且 q 是一个浮点数
  • 浮点数仍然是 32 位值,所以它们可以用作查找表的索引。而且,根据所需的精度,您可以将p+q 存储为 64 位定点数,其中小数部分为 32 位,整数部分为 32 位。
  • 更好的是,一旦你这样做了,你可以试试这里解释的right-to-left binary method
  • 您尝试解决的原始问题是什么?也许日志不是朝着正确方向迈出的一步。

标签: algorithm integer exponentiation


【解决方案1】:

如果您需要答案mod N,您通常可以完成整个计算的每一步mod N。这样,您就永远不会超出系统的整数大小限制。

【讨论】:

  • 不,我需要 mod M。是的,我这样做了,但是我如何将一个数字取为模 M 的实际幂?
  • 是的,确切地说:您将如何进行模幂运算? :-)
  • 整数到整数的模幂运算很容易,但是整数到浮点数呢?
  • 麻烦的不是求幂,而是除法。
【解决方案2】:

虽然将大量数字用作日志通常是一种不错的方法,但在这里却行不通。问题是在日志空间中工作会丢弃最低有效数字,因此您丢失了信息,并且无法返回。在 mod 空间工作也会丢掉信息(否则你的数字会变得很大,正如你所说),但它会丢掉最重要的信息。

对于您的特定问题POWERMUL,我要做的是计算从1N 的数字的素数分解。您必须小心操作,因为您的 N 相当大。

现在,如果你的数字是 k{2: 3, 5: 2} 的素因式分解,你会得到 k^m 的因式分解 {2: m*3, 5:m*2}。除法同样变成减法。

一旦您获得了f(N)/(f(r)*f(N-r)) 的素数分解表示,您就可以使用模乘和取幂的组合重新创建整数。后者是一种很酷的查找技术。 (事实上​​,像 python 这样的语言已经内置了 pow(3, 16, 7)=4

玩得开心:)

【讨论】:

  • 质数分解 n 数的最佳方法是什么?大约有 10^4 个素数,直到 10^5
  • 使用埃拉托色尼筛通常是最快的。但是,更多地考虑您的问题,您可能会想出一个更快的方法。考虑“2^2*4^4*6^6...中有多少二的因数”等。
  • 是的,但仍然是 10^5*10^4 个素数 = O(10^9) 步
  • 使用我之前评论的技术,你没有得到10^5的因素。在恒定时间内(用笔和纸)我计算出 2 除以 '1^1*2^2*3^3*...*(10^5)^(10^5)' 5000265024 次。 (实际上是 logN 时间)。
  • 是的,但我需要每隔多少次素数除以它,而 10^5 来自查询需要 '1^1*2^2*3^3*.. .*r^r 代表所有 r
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-02
相关资源
最近更新 更多