power and modulo on the fly for big numbers

后端 未结 3 536
春和景丽
春和景丽 2021-01-13 07:26

I raise some basis b to the power p and take the modulo m of that.

Let\'s assume b=55170 or 55172 and m=3043839241 (which happens to be the square of 55171). The li

3条回答
  •  庸人自扰
    2021-01-13 08:03

    I think the answer is here:

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

    That means you can have a long overflow even for numbers which are less than that particular module value. Let's try to catch it:

    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
    

    There you have it.

提交回复
热议问题