Странный вывод из Java Typecast

Я играю с простым шифрованием с использованием алгоритмов RSA и обнаружил странную ошибку.

private static Integer testEnc(Integer value){
    Integer val = (int)Math.pow(value, 37);
    return val % 437; 
}

private static Integer testDec(Integer value){
    Integer val = new Integer((int)Math.pow(value, 289));
    return val % 437;
}

public static void main(String[] args) {
    System.out.print("Encode 55  = ");
    Integer encoded = testEnc(2);
    System.out.println(encoded + "\n");

    System.out.print(encoded + " decoded = ");
    Integer decoded = testDec(3977645);
    System.out.println(decoded + "n");
}

Обе следующие функции возвращают 97 независимо от ввода. Если я закомментирую модуль и просто верну val, возвращаемое значение будет 2147483647.

Кажется, проблема в приведении типа double к int, но я не уверен, почему это так. Эти методы являются статическими только потому, что я вызывал их из основного метода.

2 ответа

Решение

2147483647 - это максимальное значение типа int, то есть 2^31-1. Для любого значения>=2 вы получаете переполнение, потому что 2^37 > 2^31-1

Чтобы получить мощность по модулю 437, вы должны получать по модулю на каждом шаге. Например, как:

private static int myPow(int a, int b, int mod){
    int ret = 1;
    for(int i = 0; i < b; i++)
    {
        ret = (ret * a) % mod;
    }
    return ret;
}

2147483647 - это наибольшее 32-разрядное целое число со знаком. Я предполагаю, что ваши тестовые значения для 37-й и 289-й степеней больше, чем могут быть сохранены в int. Попробуйте использовать длинный и посмотреть, что произойдет.

Другие вопросы по тегам