Не ловится исключение Devision by zero

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

Ответить
forlazarus
новенький
Сообщения: 15
Зарегистрирован: 28.10.2021 10:29:33

Не ловится исключение Devision by zero

Сообщение forlazarus »

Код должен выдать сообщение типа "Floating point devision by zero". А его нет.
Вместо этого в заголовке окна пишется +Inf.

Код: Выделить всё

function y(x: Double): Double;
begin
 y:=1/x
end;

procedure TForm1.Button1Click(Sender: TObject);
Var x: Double;
begin x:=0;
 Form1.Caption:=floattostr(y(x));
end; 


Подскажите, пожалуйста, почему так и как поймать.
lazarus 2.0.12

P.S.Проверка деления на нуль в этом случае сводится к (например)

Код: Выделить всё

if pos('Inf',floattostr (y(x)))>0
then exit(false)
else exit(true);
Последний раз редактировалось forlazarus 07.11.2021 12:45:06, всего редактировалось 1 раз.
Аватара пользователя
runewalsh
энтузиаст
Сообщения: 579
Зарегистрирован: 27.04.2010 00:15:25

Сообщение runewalsh »

Сделай в начале работы программы (можно прям в основном begin-end в файле проекта, наверное)

Код: Выделить всё

uses Math;
SetExceptionMask(GetExceptionMask - [exZeroDivide]) // или плюс, не уверен :D

Если exZeroDivide не (?) в маске, флоатовые деления на ноль бросают исключение. Если в (?) маске, возвращают бесконечность (при делении не-0 на 0) или NaN (0 / 0). Вообще-то второй вариант практически всегда удобнее, и даже корректнее: если целочисленный ноль — это ровно ноль, то флоатовый ноль может означать слишком малое для представления число.

>P.S.Проверка деления на нуль в этом случае сводится к (например)
Почему бы просто не сравнить знаменатель с нулём перед делением?
forlazarus
новенький
Сообщения: 15
Зарегистрирован: 28.10.2021 10:29:33

Сообщение forlazarus »

runewalsh писал(а):

Код: Выделить всё

uses Math;
SetExceptionMask(GetExceptionMask - [exZeroDivide]);


Спасибо большое,
Теперь вроде как надо:
Проект project1 вызвал класс исключения 'External: SIGFPE'.
В файле 'unit1.pas' на строке 34:
y:=1/x


Почему бы просто не сравнить знаменатель с нулём перед делением?

В общем случае обрабатываются любые функции, например, квадратный корень из икс или логарифм. В каждой функции свои особенности ОДЗ.

Надеюсь в лазарусе исключения будут ловится. В старых версиях оно работало.
А еще точнее, функция заранее неизвестна, есть ли в ней знаменатель вообще.

Добавлено спустя 1 час 8 минут 53 секунды:
try except end не работает

Код: Выделить всё

begin
try
y:=1/x
except
showmessage('Исключение')
end;


Извините, может, спрашиваю очевидное, но теперь окно с ошибкой появляется даже в блоке try except end, но исключение должно перехватываться.
Запутался я :oops:

В Delphi 7 код работает, как положено, с перехватом исключения.
zub
долгожитель
Сообщения: 2889
Зарегистрирован: 14.11.2005 22:51:26
Контактная информация:

Сообщение zub »

при запуске под иде (под отладчиком) в работу вмешивается отладчик, это он перехватывает исключения. при запуске без иде - будет работать только твоя обработка
также для работы try except нужна инициализация модуля SysUtils
forlazarus
новенький
Сообщения: 15
Зарегистрирован: 28.10.2021 10:29:33

Сообщение forlazarus »

zub писал(а):при запуске под иде (под отладчиком) в работу вмешивается отладчик, это он перехватывает исключения. при запуске без иде - будет работать только твоя обработка


Вы правы. Действительно, без IDE работает перехват.
Только в Сервис->Параметры... -> Отладчик (Исключения языка) галочка снята с "Уведомлять об исключениях".
Если я правильно понимаю, это должно было запретить появляться дефолтным сообщениям об ошибках.
Ответить