Camellia在其关键时间表中使用6个sigma,值为
Sigma1 = 0xA09E667F3BCC908B;
Sigma2 = 0xB67AE8584CAA73B2;
Sigma3 = 0xC6EF372FE94F82BE;
Sigma4 = 0x54FF53A5F1D36F1C;
Sigma5 = 0x10E527FADE682D1D;
Sigma6 = 0xB05688C2B3E6C1FD;
山茶花的规范文件说“Sigmas被定义为从第二个十六进制位置到第二个十六进制位置的连续值 第i个素数的平方根的十六进制表示的第十七个十六进制位置。“
在这种情况下,第i个素数是2,3,5,7,11,13
但是我找不到计算这些常数的方法。计算素数的平方根很简单,但这些小数平方根如何转换成十六进制表示法?如何在c#中实现?
答案 0 :(得分:2)
你需要的是一些主要计算平方根的方法。
请参阅以下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
值,请尝试以下平方根计算here。