Модульная экспонента в Java (алгоритм дает неправильный ответ)

1

Я пытаюсь реализовать модульную экспансионизацию, но я не могу получить правильный ответ:

public static 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
Теги:
exponentiation

1 ответ

1

Вы ничего не делаете для экспоненциальных бит нуля. Вы не получите одинаковые результаты для показателя степени 2 0 и показателя 2 2048?

Эти утверждения должны выходить из предложения 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;
  }

}
  • 1
    СПАСИБО МНОГО СЕЙЧАС ЭТО ОК
  • 0
    Это может быть мой любимый комментарий StackOverflow когда-либо.
Показать ещё 5 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню