Меню

Паскаль ошибка деления на ноль

Лучший ответ Сообщение было отмечено theone как решение

Решение

theone

Assembler
1
2
3
4
5
seg000:00B1                 mov     ax, word_1129A
seg000:00B4                 cwd
seg000:00B5                 mov     cx, 2
seg000:00B8                 idiv    cx
seg000:00BA                 mov     word_1129E, ax

При изменении делителя на 2 подключается знаковое деление(idiv).

При использовании longint подключается процедура:

Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
seg003:0769 @$brdiv$q7Longintt1 proc far
seg003:0769                 cmp     byte_112AE, 2
seg003:076E                 jb      loc_10F37
seg003:0770                 shl     eax, 10h
seg003:0774                 shrd    eax, edx, 10h
seg003:0779                 shl     ecx, 10h
seg003:077D                 shrd    ecx, ebx, 10h
seg003:0782                 jz      loc_10F82
seg003:0784                 cdq
seg003:0786                 idiv    ecx
seg003:0789                 mov     ecx, edx
seg003:078C                 shld    edx, eax, 10h
seg003:0791                 shld    ebx, ecx, 10h
seg003:0796                 retf
seg003:0797 loc_10F37:
seg003:0797                 push    bp
seg003:0798                 xor     bp, bp
seg003:079A                 or      dx, dx
seg003:079C                 jns     loc_10F46
seg003:079E                 inc     bp
seg003:079F                 neg     ax
seg003:07A1                 adc     dx, 0
seg003:07A4                 neg     dx
seg003:07A6 loc_10F46:
seg003:07A6                 or      bx, bx
seg003:07A8                 jz      loc_10F88
seg003:07AA                 jns     loc_10F57
seg003:07AC                 inc     bp
seg003:07AD                 inc     bp
seg003:07AE                 neg     cx
seg003:07B0                 adc     bx, 0
seg003:07B3                 neg     bx
seg003:07B5                 jz      loc_10F8A
seg003:07B7 loc_10F57:
seg003:07B7                 push    bp
seg003:07B8                 mov     si, cx
seg003:07BA                 mov     di, bx
seg003:07BC                 xor     bx, bx
seg003:07BE                 mov     cx, dx
seg003:07C0                 mov     dx, ax
seg003:07C2                 xor     ax, ax
seg003:07C4                 mov     bp, 10h
seg003:07C7 loc_10F67:
seg003:07C7                 shl     ax, 1
seg003:07C9                 rcl     dx, 1
seg003:07CB                 rcl     cx, 1
seg003:07CD                 rcl     bx, 1
seg003:07CF                 inc     ax
seg003:07D0                 sub     cx, si
seg003:07D2                 sbb     bx, di
seg003:07D4                 jnb     loc_10F7B
seg003:07D6                 dec     ax
seg003:07D7                 add     cx, si
seg003:07D9                 adc     bx, di
seg003:07DB loc_10F7B:
seg003:07DB                 dec     bp
seg003:07DC                 jnz     loc_10F67
seg003:07DE                 pop     bp
seg003:07DF                 jmp     short loc_10F97
seg003:07E1 loc_10F81:
seg003:07E1                 pop     bp
seg003:07E2 loc_10F82:
seg003:07E2                 mov     ax, 0C8h ; 'L'
seg003:07E5                 jmp     loc_108AF
seg003:07E8 loc_10F88:
seg003:07E8                 jcxz    loc_10F81
seg003:07EA loc_10F8A:
seg003:07EA                 xchg    ax, bx
seg003:07EB                 xchg    ax, dx
seg003:07EC                 div     cx
seg003:07EE                 xchg    ax, bx
seg003:07EF                 div     cx
seg003:07F1                 mov     cx, dx
seg003:07F3                 mov     dx, bx
seg003:07F5                 xor     bx, bx
seg003:07F7 loc_10F97:
seg003:07F7                 shr     bp, 1
seg003:07F9                 jnb     loc_10FA3
seg003:07FB                 neg     cx
seg003:07FD                 adc     bx, 0
seg003:0800                 neg     bx
seg003:0802                 inc     bp
seg003:0803 loc_10FA3:
seg003:0803                 dec     bp
seg003:0804                 jnz     loc_10FAD
seg003:0806                 neg     ax
seg003:0808                 adc     dx, 0
seg003:080B                 neg     dx
seg003:080D loc_10FAD:
seg003:080D                 pop     bp
seg003:080E                 retf
seg003:080E @$brdiv$q7Longintt1 endp

Ваше прерывание выглядит так:

Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
seg000:001C                 push    ax
seg000:001D                 push    bx
seg000:001E                 push    cx
seg000:001F                 push    dx
seg000:0020                 push    si
seg000:0021                 push    di
seg000:0022                 push    ds
seg000:0023                 push    es
seg000:0024                 push    bp
seg000:0025                 mov     bp, sp
seg000:0027                 sub     sp, 4
seg000:002A                 mov     ax, seg dseg
seg000:002D                 mov     ds, ax
seg000:002F                 mov     word ptr [bp-4], 0Ah
seg000:0034                 mov     word ptr [bp-2], 0
seg000:0039                 mov     ax, [bp-4]
seg000:003C                 mov     dx, [bp-2]
seg000:003F                 mov     cx, 1
seg000:0042                 xor     bx, bx
seg000:0044                 call    @$brdiv$q7Longintt1
seg000:0049                 mov     ax, cx
seg000:004B                 mov     dx, bx
seg000:004D                 or      ax, dx
seg000:004F                 jnz     $+2
seg000:0051                 mov     sp, bp
seg000:0053                 pop     bp
seg000:0054                 pop     es
seg000:0055                 pop     ds
seg000:0056                 pop     di
seg000:0057                 pop     si
seg000:0058                 pop     dx
seg000:0059                 pop     cx
seg000:005A                 pop     bx
seg000:005B                 pop     ax
seg000:005C                 iret

Но оно вызывает функцию @$brdiv$q7Longintt1, где используются 32-х битные регистры, ладно младшие 16-ть бит востанавливаются(куча push и pop вначале и в конце), но старшая часть регистра перезаписывается 18,2 раза в секунду(в прерывании), плюс ещё программа вносит свои изменения в цикле.

До тех пор, пока Вы не раскажите о хитрых ходах: a mod 1 = 0 и newtick div 1 смысла разговаривать нет.

Добавлено через 15 минут
Ваша программа выполненяет newtick div 1 в цикле и прерывается прерыванием и выполняя a mod 1 = 0 заходит в общую функцию, при этом портит сами регистры(старшую часть) именно это приводит к ошибке.
Я бы посоветовал использовать критические секции, но в этом паскале/ассемблере, кроме как запрета прерываний ничего нет.



2



Неописанная переменная

begin
  S := 1; // Неизвестное имя S
end.

Все используемые переменные должны быть предварительно описаны с помощью ключевого слова var (внутри блока begin/end или, что обычно хуже, в разделе описаний вначале программы).

Отсутствующая ;

begin
  var S: integer 
  S := 1;         // Компилятор здесь скажет: Ожидалась ; — имеется ввиду предыдущая строка!
end.
begin
  var S := 1 
  S := S + 1  // Аналогично: проблема на предыдущей строке, а на текущей нет, потому что после неё идёт end.
end.

Очень частая ошибка у начинающих. Курсор, как правило, позиционируется в начале следующей строки.

Несовместимость типов при присваивании

begin
  var S: integer := 1.3; // Нельзя преобразовать тип real к integer
end.

Безболезненно можно присваивать только данные одного типа. Если данные — разных типов, то в редких случаях можно преобразовать данные одного типа в данные другого. Например, целое можно преобразовать в вещественное, а символ — в строку. Обратные преобразования не допускаются.

Чтобы не ошибаться в подобных простых случаях в Паскале есть следующая краткая форма объявления и инициализации переменной:

begin
  var S := 1.3; // Тип real будет выведен компилятором автоматически
end.

Отсутствие закрывающего апострофа литеральной строки

begin
  var x := 2;   // x получает тип integer
  var y := 3;   // y получает тип integer
  writeln('Результат сложения равен =, x + y); // Не хватает закрывающего апострофа
end.

Закрыть апостроф надо на той же строке, где расположен открывающий апостроф

Ошибки расстановки запятых и апострофов при выводе строк и выражений

begin
  var x := 2;   // x получает тип integer
  var y := 3;   // y получает тип integer
  writeln(x, '+,' y, '=', x+y); // Неверная расстановка запятых и апострофов
end.

Слишком много запятых и апострофов рядом, потому начинающие часто путаются 🙂
Надо уяснить правила:

  • запятые разделяют разные элементы вывода
  • все, что находится в апострофах, будет выведено на экран без изменений

Ошибка ввода

begin
  var x: integer;
  read(x); // введите блаблабла и посмотрите, что получится
end.

Это — ошибка во время выполнения. Программа пытается преобразовать введенную строку в число, не может это сделать и завершается с ошибкой.

Аналогичный фрагмент в более современном и предпочтительном синтаксисе:

begin
  var x := ReadInteger;
end.

Ошибка неинициализированной переменной

begin
  var x: integer;
  // Забыли инициализировать или ввести x
  var r := x * x;  // r получает тип integer
  writeln('Квадрат числа ', x, ' = ', r);
end.

Перед использованием любую переменную надо ввести или присвоить ей начальное значение. Это действие называется инициализацией переменной.

Деление на 0

begin
  var x := 0;
  var c := 666 div x; // Здесь происходит деление на 0
end.

Если во время выполнения программа выполнит деление на 0, то она завершится с ошибкой.

Корень из отрицательного числа

begin
  writeln(sqrt(-1)); // Корень из отрицательного числа 
end.

В обычном Паскале возникает ошибка времени выполнения.
В PascalABC.NET выводится NaN — Not a Number

Ссылки

  • Программы для начинающих
  • Сайт PascalABC.NET: Программы и алгоритмы для начинающих
uses crt;
var i,k:word;
BEGIN
clrscr;

asm
mov cx, i { ; это будет i}
mov si, k {; это будет k}
mov bx, 11 {; число для вычисления модуля}

@l0:
cmp cx, 199 {; если i больше или равно 199 выходим из цикла}
jge @ext1

mov ax, si
shr ax, 1 {; деление k на 2}
add ax, cx {; добавляем i}
xor dx, dx {; очищаем dx для деления}
div bx {; делим на 11}

cmp dx, 5{ ; сравниваем остаток}
jnz @label2{ ; если не равен 5 - то на label2}

sub cx, si{ ; иначе i = i - k}
jmp @l0 ; {в начало цикла}

@label2:
mov ax, si {; подготавливаем деление}
xor dx, dx
mul ax {; умножаем на себя (k*k)}
mov dx, cx
shr dx, 1 {; делим i на 2 }
add ax, dx {; добавляем к резульату k*k}
mov si, ax {; заносим результат в k }
jmp @l0 {; в начало цикла}

@ext1:
{... ; обработка результата}
end;
writeln('REZULTAT-ASSAMBLER');
writeln('k=',k,' i=',i);
readkey;
end.

сам цикл таков

i:=57; k:=19;
while i<199 do
if ((i + k div 2) mod 11) = 5 then i:=i-k else k:=k*k+(i div 2)

Сообщение отредактировано: volvo — 18.01.2007 15:18

 
Genious
 
(2002-02-16 17:47)
[0]

Народ кто-нибудь знает как сделать простой обработчик ошибок на Pascal»е. Смысл в том, что если происходит недопустимая арифметическая операция(например: деление на ноль или логарифм из отрицательного числа) мне надо ее обработать.


 
Desdechado
 
(2002-02-16 18:17)
[1]


 
panov (M)
 
(2002-02-16 18:43)
[2]

обрабатывай в блоке try..except…end


 
APL
 
(2002-02-17 12:25)
[3]

а можно и так

function Mydiv(x,y:real):real;

begin

if y=0 then

result:=0

else

result:= x/y;

end;


 
AlexKniga
 
(2002-02-17 15:20)
[4]

Как я понял, нужно сделать обработчик исключений на Turbo Pascal»е.

Program RTE;

Procedure Main;

Var Value: Double;

Begin

Repeat

WriteLn;

ReadLn (Value);

WriteLn (1/Value); //при вводе нуля получим RTE 200

Until Value=9999;

End;

Var ExitStandart: Pointer;

Procedure MyExit; far; // мой обработчик исключений

Begin


ExitProc:=ExitStandart;

If
ErrorAddr<>nil Then

Case
ExitCode of

200:

Begin

ErrorAddr:=nil;

WriteLn ("Division by zero!");

ExitProc:=@MyExit;

Main

End

Else

End;

ReadLn;

End;

Begin

ExitStandart:=
ExitProc;

ExitProc:=@MyExit;

Main

End.

Почитай хелп по выделенному.

Аналогично обрабатываются все run time error»ы.

Можно реализовать
самому все возмозности try..except…end.

Т.е. каскадную обработку исключений, возбуждение собственных и пр.


Добрый день!
Недавно начал учиться программированию, ещё более недавно — Паскалю в Лазарусе.
Делаю незамысловатую игру, пока что без сторонних библиотек, средствами ИДЕ. ОС — Линукс Xubutnu.
Возникает периодически ошибка такого плана:

Проект вызвал класс исключения ‘External: Unknown exception code 8’.
В файле ‘laztracer.pas’ на строке 50
LazTracer, в свою очередь, указывает на такую строку:

procedure RaiseGDBException(const Msg: string);
begin
DebugLn(lrsERRORInCode, Msg);
// creates an exception, that gdb catches:
DebugLn(lrsCreatingGdbCatchableError);
DumpStack;
{$ifndef HASAMIGA} // On Amiga Division by 0 is not catchable, just crash
if (length(Msg) div (length(Msg) div 10000))=0 then ;
{$endif}
end;

Происходит это временами, всё чаще. Последний раз после того, как в модуле попытался присвоить переменной случайное значение:

function filler(var name: string): Oblast;
var
Obl: Oblast;
RandBG: integer;
begin
Randomize;
RandBG:= Random(3);

После этого я изменил код, удалив всё, что написал с момента, когда программа работала исправно:

function filler(var name: string): Oblast;
var
Obl: Oblast;
begin

Не помогло. Тогда запустил программу без ИДЕ. Она тоже сообщила о делении на ноль, но, после того, как я проигнорировал это сообщение, запустилась. И через ИДЕ после этого снова всё собралось… А потом (ничего не менял, просто попробовал ещё раз запустить в ИДЕ) — опять не работало…
Короче, я не вижу связи между этим сообщением и своими действиями. То работает, то нет.
Иногда появляется сообщение и после каких-то других действий. Откатываюсь назад, пишу снова вроде то же самое — работает.
Короче, работать невозможно. Подскажите, в чём может быть беда. Или хотя бы направление, в котором надо копать.
Спасибо.

0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
guest

0 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии

А вот еще интересные материалы:

  • Яшка сломя голову остановился исправьте ошибки
  • Ясность цели позволяет целеустремленно добиваться намеченного исправьте ошибки
  • Ясность цели позволяет целеустремленно добиваться намеченного где ошибка
  • Пациенту необходима неотложная экстренная помощь ошибка
  • Паскаль ошибка встречен конец файла а ожидался оператор