r - 在 r 中找到对 pi 最小的分数
问题描述
我正在尝试编写一个函数来输出最小公共分数n/d
,其中min <= d <= max <= |(n/d) - pi|
那是:
n
是分子
d
是分母
和是边界,即搜索min
和之间的所有分母。max
d
min
max
如果
d = 1
:3/1 <= pi <= 4/1
,给出最接近的分数3/1
分数|3/1 - pi| = 0.142
...
如果
d = 4
:12/4 <= pi <= 13/4
,给出距离为 的最接近的13/4
分数|13/4 - pi| = 0.108
...
如果
d = 6
:18/6 <= pi <= 19/6
,给出19/6
距离为的最近的分数|19/6 - pi| = 0.025
如果
d = 7
:21/7 <= pi <= 22/7
,给出距离为 的最接近的22/7
分数|22/7 - pi| = 0.001
...
If
d = 10
:31/10 <= pi <= 32/10
给出距离为 的最接近的31/10
分数|31/10 - pi| = 0.042
因此,在这里,最好的近似值是距离到的22/7
时间和地点d = 7
pi
0.001
min = 1
max = 10
library(Rmpfr)
Const("pi", 3333) # pi correct to 1000 decimal places
1 'mpfr' number of precision 3333 bits
[1] 3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266482133936072602491412737245870066063155881748815209209628292540917153643678925903600113305305488204665213841469519415116094330572703657595919530921861173819326117931051185480744623799627495673518857527248912279381830119491298336733624406566430860213949463952247371907021798609437027705392171762931767523846748184676694051320005681271452635608277857713427577896091736371787214684409012249534301465495853710507922796892589235420199561121290219608640344181598136297747713099605187072113499999983729780499510597317328160963185950244594553469083026425223082533446850352619311881710100031378387528865875332083814206171776691473035982534904287554687311595628638823537875937519577818577805321712268066130019278766111959092164201989381
解决方案
下面的函数在整个分母范围内找到最佳近似值(并替换了我之前发布的一个效率极低的函数。如果你想开怀大笑,请查看编辑历史)。
findBestApprox <- function(minD, maxD) {
lowers <- floor(pi*(minD:maxD))/(minD:maxD)
i <- which.min(abs(pi - lowers))
best.lower <- lowers[i]
uppers <- ceiling(pi*(minD:maxD))/(minD:maxD)
j <- which.min(abs(pi - uppers))
best.upper <- uppers[j]
if(abs(pi - best.lower) < abs(pi - best.upper)) {
d <- minD + i - 1
n <- floor(pi*d)
} else {
d <- minD + j - 1
n <- ceiling(pi*d)
}
c(n,d)
}
例如
> findBestApprox(2,1000)
[1] 355 113
> 355/113
[1] 3.141593
代码的矢量化特性使其速度非常快,只需一秒钟左右即可搜索到 1000 万条:
> findBestApprox(2,10000000)
[1] 5419351 1725033
> format(5419351/1725033,digits = 16)
[1] "3.141592653589815"
> 5419351/1725033 - pi
[1] 2.220446e-14
推荐阅读
- ios - 如何缩放和定位附加了 SCNSkinner 的 SCNNode?
- grails - 可以通过realation domain Class来约束gorm标准吗?
- amazon-s3 - 将服务器从本地重新路由到亚马逊?
- typescript - 找不到任务“功能:主机启动”
- javascript - 设置变换翻译
使用 Javascript - node.js - 有没有办法暂停redis服务器?
- acumatica - PXTimeSpanLong(Format = TimeSpanFormatType.????) 没有给出正确的输出/输入
- python - Numpy广播数组到更小的数组,每行都有精确的位置
- html - 如何清除ajax成功显示的先前搜索结果?
- arrays - 根据值出现的次数对 Ruby 哈希数组进行排序