私はオイラーのTotient関数のバージョンを動作させることができましたが、小さい数値で動作するものはあります(ここでは、計算に必要な1024ビット数値と比較して小さいです)
私のバージョンはここにあります -
public static BigInteger eulerTotientBigInt(BigInteger calculate) {
BigInteger count = new BigInteger("0");
for(BigInteger i = new BigInteger("1"); i.compareTo(calculate) < 0; i = i.add(BigInteger.ONE)) {
BigInteger check = GCD(calculate,i);
if(check.compareTo(BigInteger.ONE)==0) {//coprime
count = count.add(BigInteger.ONE);
}
}
return count;
}
これは小さい数値に対しては機能しますが、1 から計算中の数値まで可能な限りすべて反復することによって機能します。大きな BigInteger では、これはまったく実行不可能です。
各反復で数を分割することが可能であり、それらを1つずつ処理する必要がなくなることを読みました。何を何で割るべきかわかりません (私が見た例のいくつかは C であり、long と平方根を使用しています - 私の知る限り、正確な正確な計算はできませんBigInteger の平方根また、このような剰余算術の場合、mod が何であるかを示す引数を関数に含める必要があるかどうかも疑問に思っています。
ここで誰かが私を正しい方向に向けることができますか?
PS Euler Totient Function の変更を見つけたときに、この質問を削除しました。BigIntegers で動作するように調整しました -
public static BigInteger etfBig(BigInteger n) {
BigInteger result = n;
BigInteger i;
for(i = new BigInteger("2"); (i.multiply(i)).compareTo(n) <= 0; i = i.add(BigInteger.ONE)) {
if((n.mod(i)).compareTo(BigInteger.ZERO) == 0)
result = result.divide(i);
while(n.mod(i).compareTo(BigInteger.ZERO)== 0 )
n = n.divide(i);
}
if(n.compareTo(BigInteger.ONE) > 0)
result = result.subtract((result.divide(n)));
return result;
}
そして、正確な結果が得られます.1024ビットの数値を渡すと、ビットは永遠に実行されます(終了したかどうかはまだわかりません.20分間実行されています)。