FOR/NEXT 有多个下一个命令
FOR/NEXT with multiple next commands
我必须在 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
。
是的,您只能有一个 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
这里有两个问题。
第一个是由第 2075 行的(隐含的)GOTO 语句引起的。(用 Edsger Dijkstra 的话说,GOTO 语句是 considered harmful。)在您的 FOR 循环中,第 2080-2089 行和第 2100 行-2109 在每个奇数和偶数迭代中交替执行。由于循环运行了奇数次(准确地说是 25 次),因此它会在到达第 2090 行的 NEXT I 语句时结束。之后,程序将执行到第 2100-2109 行,然后在第 2 行失败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
一个我一直用的生成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
另一种使用atn计算n位圆周率的算法:(仅在qb64中有用):
用途:16*阿坦(1/5)-4*阿坦(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
我必须在 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
。
是的,您只能有一个 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
这里有两个问题。
第一个是由第 2075 行的(隐含的)GOTO 语句引起的。(用 Edsger Dijkstra 的话说,GOTO 语句是 considered harmful。)在您的 FOR 循环中,第 2080-2089 行和第 2100 行-2109 在每个奇数和偶数迭代中交替执行。由于循环运行了奇数次(准确地说是 25 次),因此它会在到达第 2090 行的 NEXT I 语句时结束。之后,程序将执行到第 2100-2109 行,然后在第 2 行失败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
一个我一直用的生成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
另一种使用atn计算n位圆周率的算法:(仅在qb64中有用): 用途:16*阿坦(1/5)-4*阿坦(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