为什么这不起作用

时间:2015-03-19 21:56:17

标签: pascal freepascal

所以我有这段代码

program test;
var a, b, k, i, aux, j  :integer;
    ok :boolean;
begin
write('a=');
readln(a);

write('b=');
readln(b);

if a > b then
    begin
    aux := a;
    a := b;
    b := aux;
    end;

for i := a to b do
    begin
    ok := true;

    { finding the first divizor }
    k := 2;
    while i mod k <> 0 do
        k := k + 1;

    if k*k = i then { if the number i is pp }
        begin
        for j := 2 to trunc(sqrt(k)) do { check if that k is prime }
            if k mod j = 0 then
                begin
                ok := false;
                break
                end;
        end
    else
        ok := false;

    if ok then
        writeln(i);
    end;
writeln;
end.

它应该打印出ab之间的数字,它们是素数的完美平方。 示例

a=1
b=40

输出应为:

4
9
25

25 = 5 * 5 -> is prime 
9 = 3 *3 -> prime 
4 = 2* 2 -> also prime

但是我收到了这个错误:

Runtime error 216 at $0000000000400399

我知道这意味着什么......对于一些评论和尝试的东西,我认为它来自代码的这一部分

begin   

for j := 2 to trunc(sqrt(k)) do { check if that k is prime }
            if k mod j = 0 then
                begin
                ok := false;
                break
                end;
end

但我不明白为什么......

我真的需要一些帮助,我不想要更好的算法我只想知道为什么会出现这种错误。

我使用Free Pascal 2.6.2

谢谢!

1 个答案:

答案 0 :(得分:2)

错误实际上就在这里:

k := 2;
while i mod k <> 0 do
    k := k + 1;

ia的值开头。在您的示例a=1中,所以此while开始寻找以1开头的k=2的第一个除数。在k溢出为负数并达到值-1之前,它不会找到它。 sqrt(-1)会触发一个奇怪的异常,您的程序就会完成。

添加此项检查:

k := 2;
while (i mod k <> 0) and (i>=k) do
    k := k + 1;