这里我将使用符号
可以通过计算它然后应用定义来找到一个数字的连分数,但这需要至少 O(n) 位的内存才能找到一个0,一个1 ...一个n,实际上它是一个多更差。使用双浮点精度只能找到0、1 ... a 19。
另一种方法是使用这样一个事实:如果 a,b,c 是有理数,则存在唯一有理数 p,q,r 使得 1/(a+b*2 1/3 +c*2 2/3 ) = x +y*2 1/3 +z*2 2/3,即
因此,如果我使用 boost 有理库将 x、y 和 z 表示为绝对精度,我只能使用 2 1/3 的双精度准确地获得 floor(x + y*2 1/3 + z *2 2/3 )和2 2/3因为我只需要它在真实值的 1/2 以内。不幸的是,x、y 和 z 的分子和分母增长得相当快,如果你使用常规浮点数,错误会很快堆积起来。
通过这种方式,我能够在一小时内计算出0、1 ... 10000,但不知何故,mathematica 可以在 2 秒内完成。这是我的代码供参考
#include <iostream>
#include <boost/multiprecision/cpp_int.hpp>
namespace mp = boost::multiprecision;
int main()
{
const double t_1 = 1.259921049894873164767210607278228350570251;
const double t_2 = 1.587401051968199474751705639272308260391493;
mp::cpp_rational p = 0;
mp::cpp_rational q = 1;
mp::cpp_rational r = 0;
for(unsigned int i = 1; i != 10001; ++i) {
double p_f = static_cast<double>(p);
double q_f = static_cast<double>(q);
double r_f = static_cast<double>(r);
uint64_t floor = p_f + t_1 * q_f + t_2 * r_f;
std::cout << floor << ", ";
p -= floor;
//std::cout << floor << " " << p << " " << q << " " << r << std::endl;
mp::cpp_rational den = (p * p * p + 2 * q * q * q +
4 * r * r * r - 6 * p * q * r);
mp::cpp_rational a = (p * p - 2 * q * r) / den;
mp::cpp_rational b = (2 * r * r - p * q) / den;
mp::cpp_rational c = (q * q - p * r) / den;
p = a;
q = b;
r = c;
}
return 0;
}