【问题标题】:FOR/NEXT with multiple next commandsFOR/NEXT 带有多个 next 命令
【发布时间】:2019-11-07 20:11:12
【问题描述】:

我必须在 BASIC 中编写一个计算 pi 的程序。为此,我使用了 BASIC 的 FOR ... TO ... STEP 构造。

另外,我正在使用 2 个NEXT 命令,最后一个失败了。看起来它只是在程序达到循环限制时才会失败。

我的代码如下所示:

2040 LET M = 0
2050 LET P = 3
2070 FOR i = 1 TO 50 STEP 2
2075 IF M = 1 THEN 2100
2080 P = P + 4/(I*(I+2)*(I+3))
2085 M = 1
2089 PRINT P
2090 NEXT i
2100 P = P - 4/(I*(I+2)*(I+3))
2105 M = 0
2109 PRINT P
2110 NEXT i

预期结果是这样的列表:

3.2981943981943984
3.2994764494764497
3.2986049897814604
3.2992241848279003
3.2987685001616893

and so on...

我得到的错误(仅当 i 达到 50 时):

next without for in line 2110

或者,在另一个环境中

E6 at 2110 FOR/NEXT error

我在网上没有找到非常有用的文档,只有基本的FOR ... TO ... STEP ... NEXT

【问题讨论】:

  • 如果将第 2089 和 2090 行替换为 GOTO 2109 会怎样?
  • 仍在另一个环境中对其进行测试,但在第一个环境中它看起来成功了。谢谢你!编辑:是的,它的工作:)。
  • 如果不清楚,fornext 是一对。您不能通过添加另一个 next 将它们变成三重奏。
  • 我在 basic 方面很新,以为我可以使用多个 NEXT,而我每次只运行一个。谢谢你的信息!
  • “最后一个失败”是什么意思?究竟会发生什么?

标签: loops math basic


【解决方案1】:

这里有两个问题。

第一个是由第 2075 行的(隐含的)GOTO 语句引起的。(用 Edsger Dijkstra 的话来说,GOTO 语句是considered harmful。)在您的 FOR 循环中,第 2080-2089 行和第 2100-2109 行交替出现在每次奇偶迭代时执行。由于循环运行了奇数次(准确地说是 25 次),它会在到达第 2090 行的 NEXT I 语句时结束。之后,程序将跳到第 2100-2109 行,然后在第 2109 行失败2110 在没有 FOR 循环处于活动状态时遇到 NEXT 语句。

更好的方法是使用 IF...THEN...ELSE 结构来控制 FOR 循环内的流程,或者简单地将 M 的值合并到计算中,例如,通过将 M 初始化为 4第 2040 行,将第 2080 行中的 4 替换为 M,并将第 2085 行替换为 M = -M。这种方法还有一个优点是计算 pi 时只发生in one line 而不是两次。

另一个问题是你的程序产生了错误的答案!看来您是在使用Nilakantha Somayaji 发现的无穷级数来计算 pi,如下所示:

           4       4       4
pi = 3 + ----- - ----- + ----- - ...
         2.3.4   4.5.6   6.7.8

但在您的程序中,您将分母错误地​​计算为 1.3.4、3.5.6、5.7.8 等。这是一个建议的重写,应该会给你一个更好的结果:

1000 LET M = 4
1010 LET P = 3
1020 FOR I = 1 TO 50 STEP 2
1030 P = P + M / ((I+1)*(I+2)*(I+3))
1040 M = -M
1050 PRINT P
1060 NEXT I

【讨论】:

    【解决方案2】:

    是的,您只能有一个NEXT 语句。相反,使用IF .. THEN .. ELSE .. END IF 进行分支以进行两种类型的计算。

    2040 LET M = 0
    2050 LET P = 3
    2070 FOR i = 1 TO 50 STEP 2
    2075 IF M <> 1 THEN 
    2080 P = P + 4/(I*(I+2)*(I+3))
    2085 M = 1
    2089 PRINT P
    2090 ELSE
    2100 P = P - 4/(I*(I+2)*(I+3))
    2105 M = 0
    2107 END IF
    2109 PRINT P
    2110 NEXT i
    

    【讨论】:

      【解决方案3】:

      一个我一直用的生成PI的函数:

      REM 4 * (1/1-1/3+1/5-1/7...)
      REM 3.1415926
      DEFDBL A-Z
      L = 1
      DO
          X = X + 1 / L - 1 / (L + 2)
          L = L + 4
          P = 4 * X
          PRINT P
      LOOP
      END
      

      【讨论】:

      • 这个算法使用了 Gregory-Leibniz 级数,它比 OP 的方法收敛到 pi much more slowly
      • 是否有使用 Gauss-Legendre 算法的 PI QB 程序?
      • 我不熟悉QB,但算法很简单:en.wikipedia.org/wiki/…
      【解决方案4】:

      另一种使用 atn 计算 n 位 pi 的算法:(仅在 qb64 中有用): 用途:16*atan(1/5)-4*atan(1/239)

      DECLARE SUB atan239 (denom&)
      DECLARE SUB atan5 (denom&)
      DECLARE SUB PrintOut (words&)
      
      DEFLNG A-Z
      CLS
      DIM SHARED digits AS LONG
      start:
      INPUT "How many digits(10-32766)"; digits&
      IF digits& >= 10 AND digits& <= 32766 THEN
          Eat$ = ""
      ELSE
          PRINT "Invalid precision."
          GOTO start
      END IF
      words& = digits& \ 4 + 3
      DIM SHARED sum&(words& + 1), term&(words& + 1)
      start! = TIMER
      
      '16*atan(1/5)
      denom& = 3: firstword = 1: lastword = 2
      sum&(1) = 3: term(1) = 3: sum&(2) = 2000: term(2) = 2000
      DO UNTIL firstword >= words&
          CALL atan5(denom&)
          denom& = denom& + 2
      LOOP
      
      '-4*atan(1/239)
      denom& = 3: firstword = 2: remainder& = 4
      FOR x = 2 TO words&
          dividend& = remainder& * 10000 'crunch out 1st term
          term(x) = dividend& \ 239&
          remainder& = dividend& - term(x) * 239&
          sum&(x) = sum&(x) - term(x)
      NEXT x
      DO UNTIL firstword >= words&
          CALL atan239(denom&)
          denom& = denom& + 4
      LOOP
      FOR x = words& TO 2 STEP -1
          IF sum&(x) < 0 THEN 'release carries
              quotient& = sum&(x) \ 10000 'and borrows
              sum&(x) = sum&(x) - (quotient& - 1) * 10000
              sum&(x - 1) = sum&(x - 1) + quotient& - 1
          END IF
          IF sum&(x) >= 10000 THEN
              quotient& = sum&(x) \ 10000
              sum&(x) = sum&(x) - quotient& * 10000
              sum&(x - 1) = sum&(x - 1) + quotient&
          END IF
      NEXT x
      CALL PrintOut(words&)
      PRINT "computation time: "; TIMER - start!; " seconds"
      END 
      
      SUB atan239 (denom&)
          SHARED words&, firstword
          remainder1& = term(firstword) 'first divide implicitly
          remainder2& = 0: remainder3& = 0: remainder4& = 0
          denom2& = denom& + 2: firstword = firstword + 1
          FOR x = firstword TO words&
              temp& = term(x)
              dividend& = remainder1& * 10000 + temp&
              temp& = dividend& \ 57121
              remainder1& = dividend& - temp& * 57121
              dividend& = remainder2& * 10000 + temp&
              temp2& = dividend& \ denom&
              remainder2& = dividend& - temp2& * denom&
              sum&(x) = sum&(x) + temp2&
              dividend& = remainder3& * 10000 + temp&
              temp& = dividend& \ 57121
              remainder3& = dividend& - temp& * 57121
              dividend& = remainder4& * 10000 + temp&
              temp2& = dividend& \ denom2&
              remainder4& = dividend& - temp2& * denom2&
              sum&(x) = sum&(x) - temp2&
              term(x) = temp&
          NEXT x
          firstword = firstword + 1
          IF term(firstword) = 0 THEN firstword = firstword + 1
      END SUB
      
      SUB atan5 (denom&)
          SHARED words&, firstword, lastword
          FOR x = firstword TO lastword + 1
              temp& = term(x)
              dividend& = remainder1& * 10000 + temp&
              temp& = dividend& \ 25
              remainder1& = dividend& - temp& * 25&
              term(x) = temp&
              dividend& = remainder2& * 10000 + temp&
              temp& = dividend& \ denom&
              remainder2& = dividend& - temp& * denom&
              sum&(x) = sum&(x) - temp&
          NEXT x
          FOR x = lastword + 2 TO words&
              dividend& = remainder2& * 10000
              temp& = dividend& \ denom&
              remainder2& = dividend& - temp& * denom&
              sum&(x) = sum&(x) - temp&
          NEXT x
          IF term(lastword + 1) > 0 AND lastword < words& THEN lastword = lastword + 1
          IF term(firstword) = 0 THEN firstword = firstword + 1
          denom& = denom& + 2
          remainder1& = 0: remainder2& = 0
          FOR x = firstword TO lastword + 1
              temp& = term(x)
              dividend& = remainder1& * 10000 + temp&
              temp& = dividend& \ 25
              remainder1& = dividend& - temp& * 25&
              term(x) = temp&
              dividend& = remainder2& * 10000 + temp&
              temp& = dividend& \ denom&
              remainder2& = dividend& - temp& * denom&
              sum&(x) = sum&(x) + temp&
          NEXT x
          FOR x = lastword + 2 TO words&
              dividend& = remainder2& * 10000
              temp& = dividend& \ denom&
              remainder2& = dividend& - temp& * denom&
              sum&(x) = sum&(x) + temp&
          NEXT x
          IF term(lastword + 1) > 0 AND lastword < words& THEN lastword = lastword + 1
          IF term(firstword) = 0 THEN firstword = firstword + 1
      END SUB
      
      SUB PrintOut (words&)
          PRINT "pi = 3."
          FOR i = 1 TO words& \ 3
              PRINT " ";
              PRINT RIGHT$("0000" + LTRIM$(STR$(sum&(3 * (i - 1) + 2))), 4);
              PRINT RIGHT$("0000" + LTRIM$(STR$(sum&(3 * (i - 1) + 3))), 4);
              PRINT RIGHT$("0000" + LTRIM$(STR$(sum&(3 * (i - 1) + 4))), 4);
              IF i MOD 5 = 0 THEN PRINT "  :"; 12 * i
          NEXT i
          PRINT " ";
          FOR i = 3 * (words& \ 3) + 2 TO digits&
              IF i <= UBOUND(sum&) THEN
                  PRINT RIGHT$("0000" + LTRIM$(STR$(sum&(i))), 4);
              END IF
          NEXT i
          PRINT: PRINT
      END SUB
      REM end of function
      REM end of file
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-07-28
        • 1970-01-01
        • 2015-07-28
        • 1970-01-01
        • 2021-02-16
        相关资源
        最近更新 更多