我正在尝试将PyLay-Ay PSW素数测试的实现从Python转换为Java。
我认为我做得基本正确,但有一部分答案开始偏离,结果整个算法无法检测出任何素数。当算法开始使用lucas素性检验时,就会出现这种偏差。
这是部分测试的原始代码(部分
this repo
):
def U_V_subscript(k, n, U, V, P, Q, D):
k, n, U, V, P, Q, D = map(int, (k, n, U, V, P, Q, D))
digits = list(map(int, str(bin(k))[2:]))
subscript = 1
for digit in digits[1:]:
U, V = U*V % n, (pow(V, 2, n) - 2*pow(Q, subscript, n)) % n
subscript *= 2
if digit == 1:
if not (P*U + V) & 1:
if not (D*U + P*V) & 1:
U, V = (P*U + V) >> 1, (D*U + P*V) >> 1
else:
U, V = (P*U + V) >> 1, (D*U + P*V + n) >> 1
elif not (D*U + P*V) & 1:
U, V = (P*U + V + n) >> 1, (D*U + P*V) >> 1
else:
U, V = (P*U + V + n) >> 1, (D*U + P*V + n) >> 1
subscript += 1
U, V = U % n, V % n
return U, V
这里是我的Java对应部分:
static long[] UVSubscript(long k, long n, long U, long V, long P, long Q, long D){
BitSet bitDigits = convert(k);
long subscript = 1;
for (int i = bitDigits.length()-2; i >= 0; i--) {
U = U*V % n;
V = (powerModulus(V, 2, n) - 2*powerModulus(Q, subscript, n)) % n;
subscript *= 2;
if (bitDigits.get(i)){
if (((P * U + V) & 1) == 0){
if (((D*U + P*V) & 1) == 0){
U = (P*U + V) >> 1;
V = (D*U + P*V) >> 1;
}else{
U = (P*U + V) >> 1;
V = (D*U + P*V + n) >> 1;
}
} else if (((D * U + P * V) & 1) == 0){
U = (P*U + V + n) >> 1;
V = (D*U + P*V) >> 1;
}else{
U = (P*U + V + n) >> 1;
V = (D*U + P*V + n) >> 1;
}
subscript += 1;
U = U % n;
V = V % n;
}
}
return new long[]{U, V};
}
有人能帮我吗?这里是
a runnable version of the whole Python script
,如果有人感兴趣的话。这里是
a pastebin of my whole Java translation
.
聚苯乙烯
如果有人知道一个现成的Java实现的BaILePSW素数测试,我可以用它!