如何在Forth中构建素数生成器?

时间:2018-12-18 12:56:42

标签: gforth

我的目标是在Forth中建立素数生成器。不是Eratosthenes的筛网,而是两个嵌套循环,它们对数字A和数字B的所有组合进行暴力破解。在源代码中,我有一个用词表示循环,用于测试条件是否为真,并且还尝试进行嵌套循环。但是用gforth执行代码后,显示了堆栈下溢错误。也许某处缺少某种dup,但是循环中的i和j索引也可能是错误的。问题是,如果我更改代码中的某些内容,则堆栈会有所不同。这意味着,在将for循环的索引号放到屏幕上之后,将无法再访问该号。我也发现很难访问变量,因为Forth似乎根本没有变量。因此,我创建了一个辅助变量,但尚不清楚如何使用它。

我知道,代码看起来有些混乱,有人可以帮忙吗?

variable temp
: numbers
  10 0 do i . loop
;
: cond
  0 dup
  0 = if ." equal 0" endif
;
: plain
10 2 mod .
10 3 mod .
10 4 mod .
10 5 mod .
10 6 mod .
10 7 mod .
10 8 mod .
10 9 mod .
;
: plain2
10 temp !
\ 10 0 do temp @ i mod . loop
\ 10 0 do temp @ . i . loop
10 2 do temp @ i mod . cond loop
;
: cond2 ( n - n )
  10 2 do i 
  10 2 do i 
  mod .
  loop cr loop
;

: main
  \ numbers
  cond2
  \ plain
  \ plain2
;
main
CR bye

1 个答案:

答案 0 :(得分:0)

您的代码中有多个错误和重复。例如,在您的cond单词中,将0放在数据堆栈上,然后dup并将其栈顶值(即0)与0进行比较。当然,您每次都会得到true

似乎您尝试一次编写许多单词定义并在程序中使用它们,而没有仔细调试每个单词。使用Forth编程时,最好先制作(和调试)几个简短的单词,然后用它们组成更复杂的代码。我建议您阅读Starting Forth book,它很好地描述了这种方法。

关于您的代码-最好完全重写它。在这里:

: is-not-divided-by mod 0= INVERT ;

: check-prime-number true SWAP DUP 2 DO DUP I is-not-divided-by ROT AND SWAP loop DROP ;

: is-prime-number DUP 2 > IF check-prime-number ELSE DROP true THEN ; 

: prime-numbers 1 DO I is-prime-number IF I . THEN LOOP ;

现在10 prime-numbers将为您打印从1到9的质数。