为什么我的素数测试在随机化 BigInteger 时经常失败?

why is my primality test failing so often when randomizing a BigInteger?

我无法对 p 和 q 都为真,大多数结果都是假的,或者很少 p 为真但 q 为假,为什么这个测试对 p 和 q 都不为真?

BigInteger bitSize100 = new BigInteger("1").setBit(99);

for(int i = 0; i < 20; i++) {
        BigDecimal randomizer = new BigDecimal(Math.random()).multiply(new BigDecimal(bitSize100)); // get random 99 bit number
        BigInteger q = randomizer.toBigInteger().setBit(99); // must be 100 bits
        BigInteger p = q.add(q).add(BigInteger.ONE);
         System.out.println(p.isProbablePrime(100) + " " + q.isProbablePrime(100));
         
     }


output:
false false
false false
false false
false false
true false
false false
false false
false false
false false
false false
false false
false false
false false
false false
false false
false false
false false
false false
false false
false false

首先 BigDecimal randomizer = new BigDecimal(Math.random()).multiply(new BigDecimal(bitSize100)) 而不是 导致 100 位的随机性。

Math.random returns 一个 64 位大的 double 值,所以这是它可以创建的最大随机数(并且因为该值被限制在 0 到 1 之间的值,实际的随机性更小)。

您应该使用 Random.nextBytes() to fill a byte[] with random data and the BigInteger constructor that takes such a byte[] 的组合来构建您的 BigInteger。完全避免在此处遍历 doubleBigDecimal 值。

编辑:这实际上正是 .

第二:大多数数字根本就不是素数。如果您随机选择数字(甚至不排除偶数),那么其中绝大多数都不是质数。

我不知道质数的分数是多少Sophie Germain primes,但显然不是全部

因此,您的代码经过多次尝试(平均肯定超过 20 次)来找到这样的素数对并不奇怪。