FOR / NEXT与多个next命令

时间:2019-11-07 20:11:12

标签: loops math basic

我必须用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

4 个答案:

答案 0 :(得分:2)

是的,您只能有一个repalce()语句。而是使用NEXT分支出两种计算类型。

IF .. THEN .. ELSE .. END IF

答案 1 :(得分:2)

这里有两个问题。

第一个是由第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行中的M替换为4,并用M = -M替换2085行。这种方法还具有以下优势: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 :(得分:0)

一个我一直使用的生成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

答案 3 :(得分:0)

另一种使用atn来计算pi的n位数字的算法:(仅在qb64中使用full): 用途: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