Java中的计算不等于预期结果

时间:2013-12-30 21:11:42

标签: java math

我正在尝试用Java实现RSA算法。

当您查看此页面时:http://en.wikipedia.org/wiki/RSA_(algorithm)#A_working_example您可以看到此计算:

c = 65 ^ 17 mod 3233 = 2790

当我使用这个Java代码时:

double valc = Math.pow(65, 17) % 3233;
System.out.println("Expected = 2790, computed = " + valc);

结果是:

Expected = 2790, computed = 887.0

我做错了什么?

4 个答案:

答案 0 :(得分:5)

您假设浮点计算精确到疯狂的数字位数,而不是。 pow不是计算65^17的正确方法。你真的想做

65 * 65 * 65 ...

所以

result = 1;
for(ii = 0; ii < 17; ii++) result *= 65;

这将导致精度损失(它的位数多于内置类型可以表示的数字)。

查看模数计算可以显着简化这些计算的方式。请参阅示例https://math.stackexchange.com/questions/36318/modulo-arithmetic-with-big-numbers

它表明您可以执行上述操作:

result = 1;
for(ii = 0; ii < 17; ii++) {
  result *= 65;
  result = result % 3233;
}

有比这更有效的方法 - 但这会给你正确的结果。见http://jdoodle.com/a/2l

答案 1 :(得分:2)

Double没有足够的计算范围。尝试像BigInteger这样的

public static void main(String args[]) {
    BigInteger valc = new BigInteger("65");
    valc = valc.pow(17);
    valc = valc.mod(new BigInteger("3233"));
    System.out.println("Expected = 2790, computed = " + valc);
}

哪个输出

Expected = 2790, computed = 2790

答案 2 :(得分:1)

double没有足够的位(52)来精确地保持65 ^ 17.需要103位:

BigInteger.valueOf(65).pow(17).bitLength() == 103

而是使用BigInteger,它使用任意数量的位来表示精确的整数,仅受内存的限制:

BigInteger.valueOf(65).pow(17).mod(BigInteger.valueOf(3233)) == 2790

答案 3 :(得分:0)

如果您确实需要管理真实数字或有理数字,则应使用double。在这种情况下,您不需要它。使用BigInteger并查看here