scala - 大数字的动态功率和模数

标签 scala modulo

我将一些基础 b 提高到 p 的幂并取其模 m。

让我们假设 b=55170 或 55172 和 m=3043839241(恰好是 55171 的平方)。 linux计算器bc给出结果(我们需要这个来控制):

echo "p=5606;b=55171;m=b*b;((b-1)^p)%m;((b+1)^p)%m" | bc
2734550616
309288627

现在计算 55170^5606 给出了一个有点大的数字,但由于我必须进行模运算,我想我可以绕过 BigInt 的使用,因为:
(a*b) % c == ((a%c) * (b%c))%c i.e.
(9*7) % 5 == ((9%5) * (7%5))%5 =>
63 % 5    == (4     *    2) %5 =>
3         == 8 % 5

... 并且 a^d = a^(b+c) = a^b * a^c,因此我可以将 b+c 除以 2,对于偶数或奇数 ds d/2 和 d-(d/2),所以对于 8^5,我可以计算 8^2 * 8^3。

所以我的(有缺陷的)方法总是在运行中切断除数,看起来像这样:
def powMod (b: Long, pot: Int, mod: Long) : Long = { 
      if (pot == 1) b % mod else {
          val pot2 = pot/2
          val pm1 = powMod (b, pot2, mod)             
          val pm2 = powMod (b, pot-pot2, mod)           
          (pm1 * pm2) % mod 
      } 
}

并提供了一些值(value),
powMod (55170, 5606, 3043839241L) 
res2: Long = 1885539617
powMod (55172, 5606, 3043839241L) 
res4: Long = 309288627

如我们所见,第二个结果与上面的结果完全相同,但第一个结果看起来完全不同。我正在做很多这样的计算,只要它们保持在 Int 的范围内,它们似乎是准确的,但我看不到任何错误。使用 BigInt 也可以,但是太慢了:
def calc2 (n: Int, pri: Long) = {
    val p: BigInt = pri
    val p3 = p * p
    val p1 = (p-1).pow (n) % (p3)
    val p2 = (p+1).pow (n) % (p3)
    print ("p1: " + p1 + " p2: " + p2)
}

calc2 (5606, 55171) 
p1: 2734550616 p2: 309288627

(结果与 bc 相同)有人能看到 powMod 中的错误吗? ?

最佳答案

我想答案就在这里:

scala> math.sqrt(Long.MaxValue).toLong < 3043839241L
res9: Boolean = true

这意味着即使对于小于该特定模块值的数字,您也可能会出现长时间溢出。让我们试着捕获它:
scala> def powMod (b: Long, pot: Int, mod: Long) : Long = {
     |       if (pot == 1) b % mod else {
     |           val pot2 = pot/2
     |           val pm1 = powMod (b, pot2, mod)
     |           val pm2 = powMod (b, pot-pot2, mod)
     |           val partial = ((pm1 % mod) * (pm2 % mod)).ensuring(res =>
     |             res > pm1 % mod && res > pm2 % mod, "Long overflow multiplying "+pm1+" by "+pm2)
     |           partial % mod
     |       }
     | }
powMod: (b: Long,pot: Int,mod: Long)Long

scala> powMod (55170, 5606, 3043839241L)
java.lang.AssertionError: assertion failed: Long overflow multiplying 3042625480 by 3042625480

你有它。

关于scala - 大数字的动态功率和模数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2847069/

相关文章:

assembly - 68K 汇编中的模数

dataframe - 如何在 Julia 中对 DateTime 或 Time 类型进行取模?

scala - IntelliJ IDEA 13 : new Scala SBT project hasn't src directory structure generated

scala - 在元组中拆分字符串

scala - rdd.sortByKey 给出了错误的结果

json - Play 日期的 : scala Json. 格式

c++ - 整数下溢导致模数失败

java - 将 Java 项目添加到我的 Scala 项目

javascript - 如何在 JavaScript 数组上使用模和按位 XOR 运算符反转算法?

java - 计算整数到数组位置java