Сигма с ключами от Камелии
Камелия использует 6 сигм в своем ключевом графике со значениями
Sigma1 = 0xA09E667F3BCC908B;
Sigma2 = 0xB67AE8584CAA73B2;
Sigma3 = 0xC6EF372FE94F82BE;
Sigma4 = 0x54FF53A5F1D36F1C;
Sigma5 = 0x10E527FADE682D1D;
Sigma6 = 0xB05688C2B3E6C1FD;
Документы спецификации камелии гласят: "Сигмы определяются как непрерывные значения от второго шестнадцатеричного места до семнадцатого шестнадцатеричного места шестнадцатеричного представления квадратного корня i-го простого числа".
I-е простое число в этом случае равно 2,3,5,7,11,13
Однако я не могу найти способ вычислить эти константы. Вычислить квадратный корень из простого числа просто, но как эти дробные квадратные корни преобразовать в шестнадцатеричное представление? Как это можно реализовать в C#?
1 ответ
Что вам нужно, это какой-то метод вычисления квадратного корня в основном.
Пожалуйста, смотрите следующее Java-приложение.
private static final BigDecimal SQRT_DIG = new BigDecimal(150);
private static final BigDecimal SQRT_PRE = new BigDecimal(10).pow(SQRT_DIG.intValue());
private static final int HEX_DIGITS = 16;
private static final int HEX_DIGITS_REQUIRED = 16;
private static final int HEX_DIGITS_SKIPPED = 2;
// constant that puts the required number at the left hand of the decimal point
private static final BigDecimal DIGIT_MULTIPLICATION =
new BigDecimal(BigInteger.valueOf(HEX_DIGITS).pow(HEX_DIGITS_SKIPPED + HEX_DIGITS_REQUIRED));
public static void main(String[] args) {
// - starting value (prime)
BigInteger currentBI = BigInteger.valueOf(2);
// - loop 6 times
for (int i = 1; i <= 6; i++) {
// - get i'th prime
while (!currentBI.isProbablePrime(Integer.MAX_VALUE)) {
currentBI = currentBI.add(BigInteger.ONE);
}
// - as BigDecimal
BigDecimal currentBD = BigDecimal.valueOf(currentBI.longValue());
// - square root
BigDecimal sqrt = bigSqrt(currentBD);
// - put the required hex digits at the left hand of the decimal dot
BigInteger digitsAtLeft = sqrt.multiply(DIGIT_MULTIPLICATION).toBigInteger();
// - convert to hexadecimals and skip the first two digits as required
String digits = digitsAtLeft.toString(HEX_DIGITS).substring(HEX_DIGITS_SKIPPED);
// - print out
System.out.printf("%d %d %f... %s%n",
i, currentBI, sqrt, digits);
// - current++
currentBI = currentBI.add(BigInteger.ONE);
}
}
/**
* Uses Newton Raphson to compute the square root of a BigDecimal.
*
* @author Luciano Culacciatti
* @url http://www.codeproject.com/Tips/257031/Implementing-SqrtRoot-in-BigDecimal
*/
public static BigDecimal bigSqrt(BigDecimal c){
return sqrtNewtonRaphson(c,new BigDecimal(1),new BigDecimal(1).divide(SQRT_PRE));
}
private static BigDecimal sqrtNewtonRaphson (BigDecimal c, BigDecimal xn, BigDecimal precision){
BigDecimal fx = xn.pow(2).add(c.negate());
BigDecimal fpx = xn.multiply(new BigDecimal(2));
BigDecimal xn1 = fx.divide(fpx,2*SQRT_DIG.intValue(), RoundingMode.HALF_DOWN);
xn1 = xn.add(xn1.negate());
BigDecimal currentSquare = xn1.pow(2);
BigDecimal currentPrecision = currentSquare.subtract(c);
currentPrecision = currentPrecision.abs();
if (currentPrecision.compareTo(precision) <= -1){
return xn1;
}
return sqrtNewtonRaphson(c, xn1, precision);
}
Это выведет:
1 2 1.414214... a09e667f3bcc908b2
2 3 1.732051... b67ae8584caa73b25
3 5 2.236068... c6ef372fe94f82be7
4 7 2.645751... 54ff53a5f1d36f1ce
5 11 3.316625... 10e527fade682d1de
6 13 3.605551... b05688c2b3e6c1fdb
Проблема в том, что C# не знает о BigDecimal
но вы можете получить хорошую оценку decimal
значение, попробуйте следующий расчет квадратного корня здесь.