如何使用BBP公式直接计算π的第n位

如何使⽤BBP公式直接计算π的第n位
使⽤BBP公式可以直接求得⼗六进制π的第n位⽽不需要计算前n位的数(讲道理,我认为是可以计算⼗进制的第n位的,毕竟其本⾝就能直接计算出⼗进制的π,但我没试),其优点在于可以进⾏分布式计算,即将⼀个耗时的运算拆分成若⼲个运算单元在不同的机器上进⾏并⾏运算,提⾼运算效率。同时也可以⽤来测试计算机的性能。以下公式将直接求出⼗进制的π:
其中参数k代表的是所求π的精度,例如:当您希望求出π的前13位的话您只需要将k替换成13即可。其计算出来的结果
为,得出来也是⼀个⽆理数,但只有前13位代表Π。
接下来是如何求得⼗六进制π的第n位。
⾸先,您需要知道⼀个知识点:⼗进制的⼩数如何转换为⼗六进制?
例如,⼩数3.1415926转换为16进制为3.243f69a25b094,为了获取第⼀个16进制的⼩数,我们只需要取3.1415926的⼩数部
分0.1415925乘以16即可得到2.2654816,结果的整数位数即为16⼗六进制⼩数转换后端结果,再取2.2654816的⼩数部分0.2654816乘以16即可得到第⼆个16进制⼩数位,依次类推,当整数部分位10、11、12等⼤于9的数时,使⽤a、b、c等代替即可。
所以,如果需要得到16进制π的第n个数,只需要求得16^n*π即可:
其中
计算时,将式⼦中的j替换为1、4、5、6然后分别代⼊上式即可。
式⼦中的k表⽰精度,d表⽰需要计算π的哪⼀位置
继续得到
这⾥有两点值得注意:
1. 式⼦中的mod符号意为求模,即取16^(d-k)除以(8k+j)得余数,然后再除以(8k+j),这样做的⽬的是:在计算过程中就去除整数部分(因为我们
只需要的是⼩数部分,整数部分可以直接去除,这在当数据变得⾮常⼤时可以极⼤提⾼计算效率)。
2. 将求和部分拆分为两部分[0,d,正⽆穷]原因和第⼀点⼀样,这样的话后⾯的式⼦就⼀定是个⼩数。所以,真正在计算过程中⼀定要保证k>d。
然后将计算结果代⼊第⼀个式⼦中即可
最后,还需要注意的点是:代⼊之后求得的结果需要先去除整数部分然后再乘以16即可得到16进制π的第n位。并且,为了保证第⼀个式⼦中求出来的值不为负值,您可能需要在做第⼀个减法之前加上⼀个⼤于4的整数。
下⾯贴出java代码:
您需要⾸先在类中添加常量
private static final BigDecimal ONE = BigDecimal.ONE;动物学哲学
private static final BigDecimal TWO =new BigDecimal(2);
在太空中理家
private static final BigDecimal FOUR =new BigDecimal(4);
private static final BigDecimal FIVE =new BigDecimal(5);马艳丽照片
private static final BigDecimal SIX =new BigDecimal(6);
private static final BigDecimal EIGHT =new BigDecimal(8);
private static final BigDecimal SIXTEEN =new BigDecimal(16);
以下为⽅法实现代码,其中calc16dPI即表⽰计算(16^d)*π,calc16dSj即表⽰计算(16^d)*Sj,可以看到,我将k(即代码中的ACCURACY)设置为了d+10,这个数是我随便设置的,你也可以将其设置成其他的,具体影响⼤不⼤我还没研究。透水率
BigDecimal calc16dPI(int d){
return FOUR.multiply(calc16dSj(d,1)).add(BigDecimal.valueOf(3)).subtract(TWO.multiply(calc16dSj(d,4)).divideAndRemainder(ONE)[1]).subtract(cal c16dSj(d,5).divideAndRemainder(ONE)[1]).subtract(calc16dSj(d,6).divideAndRemainder(ONE)[1]).divideAndRemainder(ONE)[1];
蓝动中国
}
BigDecimal calc16dSj(int d,int j){
int ACCURACY = d +10;
BigDecimal part1 = BigDecimal.ZERO;
BigDecimal part2 = BigDecimal.ZERO;
for(int k =0; k <= d; k++){
part1 = part1.add(SIXTEEN.pow(d - k).divideAndRemainder(EIGHT.multiply(BigDecimal.valueOf(k)).add(BigDecimal.valueOf(j)))[1].divide(EIGHT.m ultiply(BigDecimal.valueOf(k)).add(BigDecimal.valueOf(j)), ACCURACY, BigDecimal.ROUND_HALF_UP));
}
for(int k = d +1; k < ACCURACY; k++){
part2 = part2.add(ONE.divide(SIXTEEN.pow(k - d).multiply(EIGHT.multiply(BigDecimal.valueOf(k)).add(BigDecimal.valueOf(j))), ACCURACY, BigDe cimal.ROUND_HALF_UP));
}
return part1.add(part2);
}
以下为测试⽅法,计算⼗六进制π的前100位,注意在结果上乘以⼀个16:
@Test
public void mainCalc(){
for(int d =0; d <100; d++){
linpackSystem.out.println("index of "+(d +1)+": "+calc16dPI(d).multiply(SIXTEEN));
}
}
运⾏结果截图:
分别得到2、4、3、15、6、10、8、8、8、5...则π的⼗六进制数应该为(整数位3是我⼿动加上去的)
参考 和
如果您有什么需要补充或者我说错的地⽅欢迎发邮件给我
bingo

本文发布于:2024-09-22 12:29:06,感谢您对本站的认可!

本文链接:https://www.17tex.com/xueshu/329189.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:需要   部分   计算   进制   整数   结果   运算   去除
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2024 Comsenz Inc.Powered by © 易纺专利技术学习网 豫ICP备2022007602号 豫公网安备41160202000603 站长QQ:729038198 关于我们 投诉建议