You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修改gforth的fibsum实现以正确使用返回栈?

如何在Gforth中使用返回栈实现Fibonacci序列求和?

学习Gforth时,我已经用多种方式实现了Fibonacci序列,下面是计算指定阶数内所有Fibonacci值之和的fibsum的三种实现。Fibonacci序列为:0 1 1 2 3 5 8 13 21 34 55 89,fibsum的输出序列为:0 1 2 4 7 12 20 33 54 88 ....

第一种实现(循环式,依赖全局变量)

variable fbsum
: fibsum ( u -- u.sum ) { p } 0 1 \ Fibonacci-Sum.
\ This sums the first u values of the Fibonacci sequence.
0 fbsum !
p 0= if drop dup else 1 fbsum ! endif
p 1 u+do
 over over +
 dup fbsum +!
 rot drop
loop
2drop fbsum ? ;

第二种实现(递归+循环,依赖全局变量)

variable fbsum
: fibsum2x ( u -- u.sum ) { p } 0 1 \ Fibonacci recursive (1)
p dup 1 > if
  dup 1- recurse swap
  2 - recurse +
  nip nip
else
  p 1 = if 1 fbsum +! endif \ Here p matches the argument to the top call!
  nip nip
endif ;
: fibsum2 ( u -- u.sum ) \ Fibonacci-Sum.
\ This sums the first u values of the Fibonacci sequence.
{ m }
0 fbsum !
m 1+ 1 u+do
  i fibsum2x drop
loop
fbsum ? ;

第三种实现(递归+循环,依赖全局变量)

variable fbsum
: fibsum3x ( u -- u.sum ) { p } 0 1 \ Fibonacci recursive (2)
p dup 1 > if
  dup 1- recurse swap
  2 - recurse +
  nip nip
else
  \ p 1 = if 1 fbsum +! endif \ Here p matches the argument to the top call!
  nip nip
endif ;
: fibsum3 ( u -- u.sum ) \ Fibonacci-Sum.
\ This sums the first u values of the Fibonacci sequence.
{ m }
0 fbsum !
m 1+ 1 u+do
  i fibsum3x
  fbsum +!
loop
fbsum ? ;

可以看到我的代码未使用返回栈,且尝试使用时失败,请问如何修改上述代码以正确使用返回栈?


修改方案:用返回栈替代全局变量,实现无状态求和

返回栈在Forth中用于临时存储数据,避免数据栈被递归或循环操作打乱,核心操作包括:

  • >r:将数据栈顶元素压入返回栈
  • r>:将返回栈顶元素弹出到数据栈
  • r@:读取返回栈顶元素,不弹出

1. 循环式实现(用返回栈存累加和)

移除全局变量fbsum,用返回栈维护累加状态:

: fibsum ( u -- sum )
    { p }
    p 0= if drop 0 exit then  \ 0阶和为0
    p 1= if drop 0 exit then  \ 1阶只有0,和为0
    0 1  \ 初始化前两个Fib数:a=0, b=1
    1 >r  \ 返回栈存入初始累加和(0+1=1)
    p 2 u+do
        over over + dup  \ 计算下一个Fib数c=a+b,复制一份用于累加
        r@ + >r  \ 累加和 += c,更新返回栈
        rot drop  \ 调整栈:将a替换为b,b替换为c
    loop
    2drop r>  \ 清理栈上的a、b,取出最终累加和
;

2. 递归式实现(用返回栈存递归参数)

用返回栈保存递归过程中的阶数参数,避免数据栈混乱,同时直接返回求和结果:

: fib-r ( n -- fib )
    dup 0= if drop 0 exit then
    dup 1= if drop 1 exit then
    1>r  \ 将当前n压入返回栈暂存
    1- recurse  \ 计算fib(n-1)
    r> 2- recurse +  \ 取出n,计算fib(n-2)并求和得到fib(n)
;

: fibsum ( u -- sum )
    dup 0= if drop 0 exit then
    dup 1= if drop 0 exit then
    1>r  \ 暂存当前u
    fib-r  \ 计算fib(u)
    r> 1- fibsum +  \ 取出u,求和sum(u-1) + fib(u)
;

修改核心要点

  • 彻底移除全局变量fbsum,用返回栈存储累加和或临时参数,代码更简洁且无副作用
  • 递归场景中,用>r暂存当前阶数,避免递归调用覆盖数据栈上的关键值
  • 循环场景中,用r@读取当前累加和,>r更新累加状态,替代全局变量的+!操作

内容的提问来源于stack exchange,提问作者Michel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 15:17:34