日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

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

發(fā)布時(shí)間:2024/3/7 编程问答 51 豆豆
生活随笔 收集整理的這篇文章主要介紹了 如何使用BBP公式直接计算π的第n位 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

使用BBP公式可以直接求得十六進(jìn)制π的第n位而不需要計(jì)算前n位的數(shù)(講道理,我認(rèn)為是可以計(jì)算十進(jìn)制的第n位的,畢竟其本身就能直接計(jì)算出十進(jìn)制的π,但我沒試),其優(yōu)點(diǎn)在于可以進(jìn)行分布式計(jì)算,即將一個(gè)耗時(shí)的運(yùn)算拆分成若干個(gè)運(yùn)算單元在不同的機(jī)器上進(jìn)行并行運(yùn)算,提高運(yùn)算效率。同時(shí)也可以用來(lái)測(cè)試計(jì)算機(jī)的性能。以下公式將直接求出十進(jìn)制的π:

其中參數(shù)k代表的是所求π的精度,例如:當(dāng)您希望求出π的前13位的話您只需要將k替換成13即可。其計(jì)算出來(lái)的結(jié)果為3.141592653589793238154767...,得出來(lái)也是一個(gè)無(wú)理數(shù),但只有前13位代表Π。

接下來(lái)是如何求得十六進(jìn)制π的第n位。
首先,您需要知道一個(gè)知識(shí)點(diǎn):十進(jìn)制的小數(shù)如何轉(zhuǎn)換為十六進(jìn)制
例如,小數(shù)3.1415926轉(zhuǎn)換為16進(jìn)制為3.243f69a25b094,為了獲取第一個(gè)16進(jìn)制的小數(shù),我們只需要取3.1415926的小數(shù)部分0.1415925乘以16即可得到2.2654816,結(jié)果的整數(shù)位數(shù)即為16十六進(jìn)制小數(shù)轉(zhuǎn)換后端結(jié)果,再取2.2654816的小數(shù)部分0.2654816乘以16即可得到第二個(gè)16進(jìn)制小數(shù)位,依次類推,當(dāng)整數(shù)部分位10、11、12等大于9的數(shù)時(shí),使用a、b、c等代替即可。

所以,如果需要得到16進(jìn)制π的第n個(gè)數(shù),只需要求得16^n*π即可:

其中

計(jì)算時(shí),將式子中的j替換為1、4、5、6然后分別代入上式即可。
式子中的k表示精度,d表示需要計(jì)算π的哪一位置

繼續(xù)得到

這里有兩點(diǎn)值得注意:

  • 式子中的mod符號(hào)意為求模,即取16^(d-k)除以(8k+j)得余數(shù),然后再除以(8k+j),這樣做的目的是:在計(jì)算過(guò)程中就去除整數(shù)部分(因?yàn)槲覀冎恍枰氖切?shù)部分,整數(shù)部分可以直接去除,這在當(dāng)數(shù)據(jù)變得非常大時(shí)可以極大提高計(jì)算效率)。
  • 將求和部分拆分為兩部分[0,d,正無(wú)窮]原因和第一點(diǎn)一樣,這樣的話后面的式子就一定是個(gè)小數(shù)。所以,真正在計(jì)算過(guò)程中一定要保證k>d。
    然后將計(jì)算結(jié)果代入第一個(gè)式子中即可
  • 最后,還需要注意的點(diǎn)是:代入之后求得的結(jié)果需要先去除整數(shù)部分然后再乘以16即可得到16進(jìn)制π的第n位。并且,為了保證第一個(gè)式子中求出來(lái)的值不為負(fù)值,您可能需要在做第一個(gè)減法之前加上一個(gè)大于4的整數(shù)。

    下面貼出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);

    以下為方法實(shí)現(xiàn)代碼,其中calc16dPI即表示計(jì)算(16^d)*π,calc16dSj即表示計(jì)算(16^d)*Sj,可以看到,我將k(即代碼中的ACCURACY)設(shè)置為了d+10,這個(gè)數(shù)是我隨便設(shè)置的,你也可以將其設(shè)置成其他的,具體影響大不大我還沒研究。

    BigDecimal calc16dPI(int d) {return FOUR.multiply(calc16dSj(d, 1)).add(BigDecimal.valueOf(3)).subtract(TWO.multiply(calc16dSj(d, 4)).divideAndRemainder(ONE)[1]).subtract(calc16dSj(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.multiply(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, BigDecimal.ROUND_HALF_UP));}return part1.add(part2);}

    以下為測(cè)試方法,計(jì)算十六進(jìn)制π的前100位,注意在結(jié)果上乘以一個(gè)16:

    @Testpublic void mainCalc() {for (int d = 0; d < 100; d++) {System.out.println("index of " + (d + 1) + ": " + calc16dPI(d).multiply(SIXTEEN));}}

    運(yùn)行結(jié)果截圖:

    分別得到2、4、3、15、6、10、8、8、8、5...則π的十六進(jìn)制數(shù)應(yīng)該為3.243f6a8885...(整數(shù)位3是我手動(dòng)加上去的)
    參考 我有點(diǎn)酷
    參考 維基百科 和 The BBP Algorithm for Pi
    如果您有什么需要補(bǔ)充或者我說(shuō)錯(cuò)的地方歡迎發(fā)郵件給我 zouheng613@163.com
    bingo

    總結(jié)

    以上是生活随笔為你收集整理的如何使用BBP公式直接计算π的第n位的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。