2015-03-19 2 views
-4

Так у меня есть этот кодПочему это не работает

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. 

И он должен напечатать числа между a и b, которые идеально квадратов с простого числа. Пример

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

Спасибо!

+0

Можете ли вы проверить на отладку на ведьм линии это произошло? –

+0

216: Ошибка общей защиты Приложение попыталось получить доступ к недопустимому пространству памяти. Это может быть вызвано несколькими проблемами: 1. Дефрагментация указателя nil 2. Попытка доступа к памяти, которая находится за пределами (например, вызов перемещения с недопустимой длиной). –

+0

Теперь я на Linux, и я не использую IDE, я просто компилирую, но если я зациклю 'trunc (sqrt (k))' на 'k-1', он работает, поэтому я думаю, что это на этой линии. – Matei

ответ

2

Ошибка на самом деле здесь:

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

i начинается со значением a. В вашем примере a=1, поэтому этот while начинает поиск первого делителя 1, начиная с k=2. Он не найдет его, пока k не переполнится до отрицательного значения и не достигнет значения -1. sqrt(-1) запускает нечетное исключение, и ваша программа заканчивается.

Добавить эту проверку:

k := 2; 
while (i mod k <> 0) and (i>=k) do 
    k := k + 1; 
Смежные вопросы