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