c++ - 使用 64 位分子和分母对 pi 的最佳有理近似值是多少?

标签 c++ c math pi

用两个 64 位整数表示的 Pi 最准确的有理对是什么?随意包括其他 int如果您愿意,请键入。
这是我想出的,但我相信它可以变得更准确,因为分母可以变得更大 - 我只是在想以 10 为底。我很确定分子应该类似于 uint64最大限度。

// c++
inline constexpr auto pi_num = 3141592653589793238ull;
inline constexpr auto pi_den = 1000000000000000000ull;
// c
const unsigned long long pi_num = 3141592653589793238ull;
const unsigned long long pi_den = 1000000000000000000ull;

最佳答案

您可以使用 continued fractions获得无理数的极好近似值。如果您以前没有遇到过连分数,这是一种将数字写成以下形式的嵌套分数系列的方法
a sample continued fraction
将越来越多的项添加到连分数中可以得到越来越好的有理数近似值。
continued fraction of π

[3; 7, 15, 1, 292, 1, 1, 1, 2, 1, 3, 1, 14, 2, 1, 1, 2, 2, 2, 2, 1, 84, 2, 1, 1, 15, 3, 13, 1, 4, 2, 6, 6, 99, 1, 2, 2, 6, 3, 5, 1, 1, 6, 8, 1, 7, 1, 2, 3, 7, 1, 2, 1, 1, 12, 1, 1, 1, 3, 1, 1, 8, 1, 1, 2, 1, 6, 1, 1, 5, 2, 2, 3, 1, 2, 4, 4, 16, 1, 161, ...]
因此我们可以编写一个小的 Python 脚本来根据这个连分数表示计算近似值,如下所示:
from fractions import *

digits = [3, 7, 15, 1, 292, 1, 1, 1, 2, 1, 3, 1, 14, 2, 1, 1, 2, 2, 2, 2, 1, 84, 2, 1, 1, 15, 3, 13, 1, 4, 2, 6, 6, 99, 1, 2, 2, 6, 3, 5, 1, 1, 6, 8, 1, 7, 1, 2, 3, 7, 1, 2, 1, 1, 12, 1, 1, 1, 3, 1, 1, 8, 1, 1, 2, 1, 6, 1, 1, 5, 2, 2, 3, 1, 2, 4, 4, 16, 1, 161]

for i in range(len(digits)):
    # Start with the last digit
    f = Fraction(digits[i]);

    # Keep rewriting it as term + 1 / prev
    for j in range(i-1, -1, -1):
        f = digits[j] + 1 / f
    
    # Stop if we overshoot
    if f.numerator >= 2**64 or f.denominator >= 2**64: break
    
    # Print the approximation we found
    print(f)
这会以越来越好的近似值打印连分数,直到我们超过适合 64 位整数的分数。这是输出:
3
22/7
333/106
355/113
103993/33102
104348/33215
208341/66317
312689/99532
833719/265381
1146408/364913
4272943/1360120
5419351/1725033
80143857/25510582
165707065/52746197
245850922/78256779
411557987/131002976
1068966896/340262731
2549491779/811528438
6167950454/1963319607
14885392687/4738167652
21053343141/6701487259
1783366216531/567663097408
3587785776203/1142027682075
5371151992734/1709690779483
8958937768937/2851718461558
139755218526789/44485467702853
428224593349304/136308121570117
5706674932067741/1816491048114374
6134899525417045/1952799169684491
30246273033735921/9627687726852338
66627445592888887/21208174623389167
430010946591069243/136876735467187340
2646693125139304345/842468587426513207
最后一个近似值是 π 的最佳近似值,我相信它适合 64 位整数。 (有可能在这个分母和下一个分母之间出现一个更好的分母,你会得到一个 64 位整数溢出,但这仍然非常接近!)因此,你想要
const uint64_t pi_num   = 2646693125139304345u;
const uint64_t pi_denom = 842468587426513207u;
This source报告说这个近似值精确到小数点后 37 位 (!):
3.14159265358979323846264338327950288418 (approximation)
3.14159265358979323846264338327950288419 (actual)
这应该足以满足您的目标。 (当然,除非您尝试设置查找 π 或类似数字的记录。^_^)

关于c++ - 使用 64 位分子和分母对 pi 的最佳有理近似值是多少?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62925107/

相关文章:

c++ - 显式删除和新建 vs 使用 unique_ptr

python - PyList_New 导致 SEGFAULT

c - 无法用 for 循环替代的 while 循环示例

javascript - WebGL - 沿行进方向旋转对象

C++11:正确的 std::array 初始化?

c++ - 如何使用递归使用嵌套循环并检查 C++ 中的数字总和

c - 如何使用 C 获取 2D 字符数组中的输入?

math - 计算叉积的方法是否会改变左手坐标?

c++ - N 位环绕的整数减法

c++ - 在 Release 中作为 QImage 加载时,相同的图像具有不同的像素数据