【问题标题】:Modular Exponentiation in java (the algorithm gives a wrong answer)java中的模幂(算法给出了错误的答案)
【发布时间】:2014-03-13 22:42:11
【问题描述】:

我正在尝试实现模幂,但我无法得到正确的答案:

公共静态 BigInteger modPow(BigInteger b, BigInteger e, BigInteger m)

{ //计算模幂并返回BigInteger类的对象

    BigInteger x= new BigInteger("1"); //The default value of x

    BigInteger power ;

    power=b.mod(m);

    String  t =e.toString(2); //convert the power to string of binary

    String reverse = new StringBuffer(t).reverse().toString();




    for (int i=0;i<reverse.length();i++ )  { //this loop to go over the string char by char by reverse

        if(reverse.charAt(i)=='1') { //the start of if statement when the char is 1
          x=x.multiply(power);
          x=x.mod(m);
          power=power.multiply(power);
          power=power.mod(m);

        } //the end of if statement



        }//the end of for loop


        return x;

    } //the end of the method modPow

【问题讨论】:

    标签: java modular exponentiation


    【解决方案1】:

    对于零的指数位,您不会做任何事情。对于 20 的指数和 22048 的指数,您不会得到相同的结果吗?

    这些语句应该来自if 子句,并在循环的每次迭代中执行,无论位是零还是一:

    power=power.multiply(power);
    power=power.mod(m);
    

    此外,使用e.testBit(i) 迭代指数位会更有效且更易于理解。即使不允许使用modPow()testBit() 也应该没问题。


    这是我的版本,包括对错误的修复和我摆脱字符串转换的建议。它似乎也适用于一般数字。它不处理负指数和其他一些特殊情况。

    public class CrazyModPow
    {
    
      public static void main(String[] argv)
      {
        for (int count = 1; true; ++count) {
          Random rnd = new Random();
          BigInteger base = BigInteger.probablePrime(512, rnd);
          BigInteger exp = BigInteger.probablePrime(512, rnd);
          BigInteger mod = BigInteger.probablePrime(1024, rnd);
          if (!base.modPow(exp, mod).equals(modPow(base, exp, mod))) {
            System.out.println("base: " + base);
            System.out.println("exp:  " + exp);
            System.out.println("mod:  " + mod);
          }
          else if ((count % 10) == 0) {
            System.out.printf("Tested %d times.%n", count);
          }
        }
      }
    
      public static BigInteger modPow(BigInteger base, BigInteger e, BigInteger m)
      {
        BigInteger result = BigInteger.ONE;
        base = base.mod(m);
        for (int idx = 0; idx < e.bitLength(); ++idx) {
          if (e.testBit(idx)) {
            result = result.multiply(base).mod(m);
          }
          base = base.multiply(base).mod(m);
        }
        return result;
      }
    
    }
    

    【讨论】:

    • 这可能是我最喜欢的 StackOverflow 评论了。
    • 我尝试了一个 512 位的数字,但它不起作用:(
    • @user2835815 我用许多不同的 512 位指数对其进行了测试,它们都有效。您尝试了哪些参数?结果如何?
    • 我使用随机类来生成数字(概率素数)
    • 它给出了一个数字,但如果你比较它,根据 BigInteger 类中的 modpow 它是不正确的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-19
    • 1970-01-01
    • 2013-09-13
    • 1970-01-01
    • 2020-09-03
    • 2023-01-30
    相关资源
    最近更新 更多