Странный вывод из 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. Попробуйте использовать длинный и посмотреть, что произойдет.