-5

So i have this code

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.

And it should print out the number between a and b that are perfect squares of an prime number. Example

a=1
b=40

The output should be :

4
9
25

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

But i get this error :

Runtime error 216 at $0000000000400399

I know what it means ... and for some commenting and trying stuff I think it comes from this part of the code

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

But i don't get why ...

I really need a little help on this, I don't want a better algorithm I just wanna know why is this error occurring.

I'm using Free Pascal 2.6.2

Thanks!

Roy Shmuli
  • 4,979
  • 1
  • 24
  • 38
Matei
  • 1,783
  • 1
  • 14
  • 17
  • Can you check on debug on witch line it's happened? – Roy Shmuli Mar 19 '15 at 22:09
  • 216: General Protection fault The application tried to access invalid memory space. This can be caused by several problems: 1. Defferencing a nil pointer 2. Trying to access memory which is out of bounds (for example, calling move with an invalid length). – Roy Shmuli Mar 19 '15 at 22:12
  • Now i'm on linux and i don't use the IDE, i just compile but if i chagne the `trunc(sqrt(k))` to `k-1` it works so i think it's on this line. – Matei Mar 19 '15 at 22:13
  • I know the error, but why is it appearing ? I google it too ... i don't use pointers, and i don't use fancy build in functions/procedures ... i don't get it . – Matei Mar 19 '15 at 22:14
  • 1
    Modify `while i mod k <> 0 do k := k + 1;` to include a `Writeln(i, k, i mod k)` and see what you get in the output. (You'll wish you had a debugger handy; be ready with Ctrl+C or Ctrl+Break.) – Ken White Mar 19 '15 at 22:20
  • @ken-white, thanks the problem as i said was when `i=1` , the `while` loop will go for ever and enter overflow . – Matei Mar 19 '15 at 22:34

1 Answers1

2

The mistake is actually here:

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

i begins with the value of a. In your example, a=1, so this while starts looking for the first divisor of 1 starting with k=2. It won't find it until k overflows to negative and reach the value -1. sqrt(-1) triggers an odd exception and your program finishes.

Add this check:

k := 2;
while (i mod k <> 0) and (i>=k) do
    k := k + 1;
mcleod_ideafix
  • 11,128
  • 2
  • 24
  • 32