递推求数
这个递推数列怎么求? 整数部分是 759903.这题最快的方法 可能就是高精度浮点数了
Block[{n=2025},IntegerPart@Nest[#+1/FractionalPart[#]&,N,2*n],n]]
wayne 发表于 2025-6-22 22:38
整数部分是 759903.
这题最快的方法 可能就是高精度浮点数了
怎么算的?
凑个热闹!
Table) &, N, Floor[(GoldenRatio + 1) n]], n], {n, 2025}]
{3, 5, 33, 38, 40, 61, 63, 65, 67, 69, 3311, 3315, 3317, 3803, 3825, 3833, 3836, 3838, 3977, 3979, 3981, 4183, 4204, 4206, 4209, 4211, 4218, 4221, 4231, 4239, 4241, 4244, 4246, 4253, 4259, 4261, 4263, 4505, 4508, 4510, 4512, 4514,
——长得慢一点的。
Table) &, N, (GoldenRatio + 1) n], n], {n, 2025}]
{11, 18, 20, 24, 26, 34, 72, 76, 78, 81, 83, 87, 89, 91, 93, 95, 104, 106, 113, 129, 131, 133, 135, 144, 146, 152, 154, 237, 239, 260, 262, 264, 266, 269, 271, 279, 287, 291, 295, 299, 302, 305, 308, 310, 312, 371, 373, 391, 395, 397, 400, 402, 的确4000位计算精度就够了,不过我计算结果位759901
下面是对应定点计算代码
#include <gmpxx.h>
#include <iostream>
#define TM 4000
int main()
{
mpz_class M=1;
int i;
for(i=0;i<TM;i++)M*=10;//generte 10^TM
mpz_class M2=M*M;
mpz_class sqrt2("14142135623730950488016887242096980785696718753769480731766797379907324784621070388503875343276415727350138462309122970249248360558507372126441214970999358314132226659275055927557999505011527820605714701095599716059702745345968620147285174186408891986095523292304843087143214508397626036279952514079896872533965463318088296406206152583523950547457502877599617298355752203375318570113543746034084988471603868999706990048150305440277903164542478230684929369186215805784631115966687130130156185689872372352885092648612494977154218334204285686060146824720771435854874155657069677653720226485447015858801620758474922657226002085584466521458398893944370926591800311388246468157082630100594858704003186480342194897278290641045072636881313739855256117322040245091227700226941127573627280495738108967504018369868368450725799364729060762996941380475654823728997180326802474420629269124859052181004459842150591120249441341728531478105803603371077309182869314710171111683916581726889419758716582152128229518488472089694633862891562882765952635140542267653239694617511291602408715510135150455381287560052631468017127402653969470240300517495318862925631385188163478001569369176881852378684052287837629389214300655869568685964595155501644724509836896036887323114389415576651040883914292338113206052433629485317049915771756228549741438999188021762430965206564211827316726257539594717255934637238632261482742622208671155839599926521176252698917540988159348640083457085181472231814204070426509056532333398436457865796796519267292399875366617215982578860263363617827495994219403777753681426217738799194551397231274066898329989895386728822856378697749662519966583525776198939322845344735694794962952168891485492538904755828834526096524096542889394538646625744927556381964410316979833061852019379384940057156333720548068540575867999670121372239475821426306585132217408832382947287617393647467837431960001592188807347857617252211867490424977366929207311096369721608933708661156734585334833295254675851644710757848602463600834449114818587655554286455123314219926311332517970608436559704352856410087918500760361009159465670676883605571740076756905096136719401324935605240185999105062108163597726431380605467010293569971042425105781749531057255934984451126922780344913506637568747760283162829605532422426957534529028838768446429173282770888318087025339852338122749990812371892540726475367850304821591801886167108972869229201197599880703818543332536460211082299279293072871780799888099176741774108983060800326311816427988231171543638696617029999341616148786860180455055539869131151860103863753250045581860448040750241195184305674533683613674597374423988553285179308960373898915173195874134428817842125021916951875593444387396189314549999906107587049090260883517636224749757858858368037457931157339802099986622186949922595913276423619410592100328026149874566599688874067956167391859572888642473463585886864496822386006983352642799056283165613913942557649062065186021647263033362975075697870606606856498160092718709292153132368281356988937097416504474590960537472796524477094099241238710614470543986743647338477454819100872886222149589529591187892149179833981083788278153065562315810360648675873036014502273208829351341387227684176678436905294286984908384557445794095986260742499549168028530773989382960362133539875320509199893607513906444495768456993471276364507163279154701597733548638939423257277540038260274785674172580951416307159597849818009443560379390985590168272154034581581521004936662953448827107292396602321638238266612626830502572781169451035379371568823365932297823192986064679789864092085609558142614363631004615594332550474493975933999125419532300932175304476533964706627611661753518754646209676345587386164880198848497479264045065444896910040794211816925796857563784881498986416854994916357614484047021033989215342377037233353115645944389703653166721949049351882905806307401346862641672470110653463493916407146285567980177933814424045269137066609777638784866238003392324370474115331872531906019165996455381157888");
mpz_class sqrt2u=sqrt2+1;
mpz_class u0=sqrt2-M;
mpz_class u1=u0+1;
mpz_class s1=1;
for(i=2;i<=2025;i++){
mpz_class v0=u0+M2/u0;
mpz_class v1=u1+M2/u1;
mpz_class r0=v0%M;
mpz_class r1=v1%M;
if(v0-r0!=v1-r1){
std::cout<<"Overflow in round "<<i<<std::endl;
return -1;
}
s1+=(v0-r0)/M;
u0=r0;
u1=r1;
}
std::cout<<s1<<std::endl;
return 0;
}
在计算了一下发现3000位精度也够了,但是2000位就不行了,第1643轮发现精度不够了 前几天在QQ群里 学到了 flint这个库, https://flintlib.org/, 让大模型 帮我写一个, 然后我稍微改改, 也能用了.
sqrt2直接用 arb_sqrt_ui 产生.
然后,我发现flint 需要我预留12000位的浮点精度才能计算出2025项.
#include <stdio.h>
#include "flint/arb.h"
int main() {
// 1. 定义计算精度(以比特为单位)。256位对于此任务足够高。
slong prec = 12000;
// 2. 声明并初始化 arb 变量。
// 'a' 将持有序列 a(n) 的当前值。
// 'inv_a' 是一个临时变量,用于存储 1/a(n-1)。
arb_t a,temp_floor, temp_frac, inv_a;
arb_init(a);
arb_init(temp_floor);
arb_init(temp_frac);
arb_init(inv_a);
// 3. 设置初始条件 a(1) = sqrt(2)
// arb_sqrt_ui 计算无符号整数的平方根。
arb_sqrt_ui(a, 2, prec);
// 4. 从 n=2 循环到 2025 进行迭代计算
for (int n = 2; n <= 2025; ++n) {
// 计算 a(n-1) 的倒数,并存入 inv_a
// arb_inv(result, source, precision)
arb_floor(temp_floor, a, prec);
arb_sub(temp_frac, a, temp_floor, prec);
arb_inv(temp_frac, temp_frac, prec);
// 更新 a: a = a + 1/(小数部分)
arb_add(a, a, temp_frac, prec);
printf("Value of a(%d): ",n); arb_printn(a, 100, 0); printf("\n");
}
// 5. 打印最终结果 a(2025)
// arb_printd 将结果以十进制形式打印到指定的位数。
printf("The value of a(2025) is:\n");
arb_printd(a, prec); // 打印约80位小数
printf("\n");
// 6. 清理内存,防止泄漏
arb_clear(a);
arb_clear(inv_a);
arb_clear(temp_floor);
arb_clear(temp_frac);
return 0;
} 如果我们拿到 $a+b\sqrt{2}+\frac{1}{a+b\sqrt{2}} = a-\frac{a}{2 b^2-a^2} + (\frac{b}{2 b^2-a^2}+b)\sqrt{2}$的整数部分的表达式的话(a,b是有理数). 这题目是可以存在完全是有理数表示的递推公式,进而高效的计算出a(n)的精确值的.
因为$a(n)=x_n+y_n\sqrt{2},x_n,y_n$是有理数 凑个热闹!——这个通项公式可以的。
Table) &, N, 2 n], n - 1], {n, 2025}]
{1, 3, 5, 33, 38, 40, 61, 63, 65, 67, 69, 3311, 3315, 3317, 3803, 3825, 3833, 3836, 3838, 3977, 3979, 3981, 4183, 4204, 4206, 4209, 4211, 4218, 4221, 4231, 4239, 4241, 4244, 4246, 4253, 4259, 4261, 4263, 4505, 4508, 4510, ..., 759901} 本帖最后由 Gongwen0519 于 2025-6-25 17:49 编辑
用maple程序跑起来还是挺快的:
> restart;
># 创建一个函数来计算并输出每一步迭代的结果
calculate_and_display := proc(n)
local initial_value, result, i, step_results, output_file, file_path;
# 设置足够高的精度
Digits := 20*n;
# 计算初始值
initial_value := evalf(sqrt(2), Digits);
result := initial_value;
# 存储每一步的结果
step_results := ;
# 执行迭代并记录每一步结果
for i from 1 to n-1 do
result := result + 1/(result - floor(result));
step_results := ;
end do;
# 输出前10步和后10步的结果
printf("迭代步骤结果(前10步和后10步):\n");
for i from 1 to min(10, n) do
printf("步骤 %3d: %d\n", i-1, step_results);
end do;
if n > 20 then
printf("...\n");
end if;
for i from max(n-9, 11) to n do
printf("步骤 %3d: %d\n", i-1, step_results);
end do;
# 构建D盘根目录下的文件路径
file_path := "D:\\iteration_results_n" || n || ".txt";
# 将完整结果保存到D盘根目录
output_file := fopen(file_path, WRITE);
if output_file = 0 then
printf("错误: 无法打开文件 %s 进行写入。请确保D盘存在且有写入权限。\n", file_path);
return FAIL;
end if;
fprintf(output_file, "迭代步骤结果 (n = %d)\n", n);
fprintf(output_file, "步骤, 结果\n");
for i from 1 to n do
fprintf(output_file, "%d, %d\n", i-1, step_results);
end do;
fclose(output_file);
printf("完整结果已保存到文件: %s\n", file_path);
# 返回最终结果
return step_results;
end proc:
# 计算n=2025的结果
final_result := calculate_and_display(2025);
# 输出最终结果
printf("当n=2025时的最终结果: %a\n", final_result);
运行结果:
迭代步骤结果(前10步和后10步):
步骤 0: 1
步骤 1: 3
步骤 2: 5
步骤 3: 33
步骤 4: 38
步骤 5: 40
步骤 6: 61
步骤 7: 63
步骤 8: 65
步骤 9: 67
...
步骤 2015: 759780
步骤 2016: 759782
步骤 2017: 759784
步骤 2018: 759786
步骤 2019: 759852
步骤 2020: 759855
步骤 2021: 759858
步骤 2022: 759895
步骤 2023: 759898
步骤 2024: 759901
完整结果已保存到文件: D:\iteration_results_n2025.txt
final_result := 759901
当n=2025时的最终结果: 759901
结果附件:
页:
[1]