Экспертная система Delphi.int.ru

Сообщество программистов
Общение, помощь, обмен опытом

Логин:
Пароль:
Регистрация | Забыли пароль?

Delphi.int.ru Expert

Другие разделы портала

Переход к вопросу:

#   

Статистика за сегодня:  


Лучшие эксперты

Подробнее »



Вопрос # 5 783

/ вопрос решён /

Здравствуйте, эксперты!

почему если сделать

var
i:real;
begin
i:=1/0;
end;

не показывается никакой ошибки типа 'division by zero'?

и в таком варианте тоже:
var
i:real;
begin
ErrorProc :=nil;
ExceptProc :=nil;
ExceptionClass :=nil;
ExceptClsProc :=nil;
ExceptObjProc :=nil;
AssertErrorProc:=nil;
i:=1/0;
end;

нужно, чтобы любые ошибки были видны.

Фамилия Имя Отчество Вопрос решён, но можно продолжить его обсуждение в мини-форуме

Вопрос задал: Фамилия Имя Отчество (статус: Посетитель)
Вопрос отправлен: 27 ноября 2011, 06:39
Состояние вопроса: решён, ответов: 2.

Ответ #1. Отвечает эксперт: Толяныч

Здравствуйте, Фамилия Имя Отчество!
Не показывает, потому что никакой операции деления тут нет.
Выражение i := 1/0 присваивает переменной i максимально возможное положительное значение. Если посмотреть отладчиком, то в i увидим +INF .

Вот цитата из хелпа по запросу "Infinity constant".

<

Unit

Math

Category

Arithmetic routines

Delphi syntax:

const Infinity = 1.0 / 0.0;

Description

Use Infinity to assign a value of positive Infinity to a floating-point variable. Do not use Infinity in comparisons. To check whether a variable or expression represents infinity, use the IsInfinite function instead.
Represents positive infinity.

>

Чтоб получить ожидаемую реакцию, нужно :

a := 0.0 ; i := 1.0/a ;

Странноватый выбор идентификатора i для real. Но это так, к слову...

Ответ отправил: Толяныч (статус: 4-ый класс)
Время отправки: 27 ноября 2011, 23:07
Оценка за ответ: 4

Комментарий к оценке: ничего не изменилось, всё равно никакой ошибка не показывает...

procedure TForm1.Button1Click(Sender: TObject);
var
  a,b,c:real;
begin
  a:=0.0;
  b:=1.0;
  с:=b/a;
end;

Ответ #2. Отвечает эксперт: Егор

Здравствуйте, Фамилия Имя Отчество!
Правы все эксперты.
Поясню на примерах:

1)

procedure TForm1.Button1Click(Sender: TObject);
var
  z : real;
begin
  z := 1 / 0;
end;
Программа откомпилируется и будет работать. Выражение 1/0 будет вычислено компилятором (об этом ниже), но затем, на фазе оптимизации, т.к. переменная z не используется, то компилятор выкинет любые упоминания этой переменной. Ошибка не возникнет.

2)
procedure TForm1.Button1Click(Sender: TObject);
var
  z : real;
begin
  z := 1 / 0;
  showmessage(floattostr(z)); // выдаст INF
end;
Программа откомпилируется и будет работать. Выдаваться будет INF, т.к. для дробных чисел предусмотрено специальное значение - бесконечность (INF). Значение это будет вычислено компилятором до запуска программы, а в текст будет подставлено именно значение INF, а не выражение 1/0.
Аналогично можно записать
z := infinity;
(должен быть подключен модуль Math).

3)
procedure TForm1.Button2Click(Sender: TObject);
var
  x, y, z : real;
begin
  x := 1;
  y := 0;
  z := x / y;   // ошибка выполнения:
                // Project Project1.exe raised exception class EZeroDivide
                // with message 'Floating point division by zero'.
                // Process stopped. Use Step or Run to continue.
  showmessage(floattostr(z));
end;
Здесь произойдёт ошибка времени выполнения. Во время работы программы будет выдано сообщение "Floating point division by zero".

4)
procedure TForm1.Button3Click(Sender: TObject);
var
  a, b, c : integer;
begin
  a := 1;
  b := 0;
  c := a div b; // ошибка выполнения:
                // Project Project1.exe raised exception class EDivByZero
                // with message 'Division by zero'.
                // Process stopped. Use Step or Run to continue.
  showmessage(inttostr(c));
end;
Т.к. числа целые (integer), то использовать операцию деления (/) нельзя. Вместо неё используется операция целочисленного деления (div).
Во время работы программы будет выдано сообщение об ошибке деления на ноль: "Division by zero".

5)
procedure TForm1.Button4Click(Sender: TObject);
var
  c : integer;
begin
  c := 1 div 0; // не скомпилируется
  showmessage(inttostr(c));
end;
Этот вариант не скомпилируется вообще, т.к. здесь идёт попытка заставить компилятор разделить нацело целое число на ноль.

5)
procedure TForm1.Button4Click(Sender: TObject);
var
  c : integer;
begin
  c := 1 div 0; // не скомпилируется
end;
Несмотря на то, что переменная с не используется, этот вариант также не скомпилируется. Причина - у нас есть выражение (1 div 0), которое надо вычислить. Вычисление будет выполнено до фазы оптимизации, поэтому процесс компиляции не будет успешным.

P.S. Все варианты проверялись в Delphi7.

Ответ отправил: Егор (статус: 10-ый класс)
Время отправки: 28 ноября 2011, 16:54
Оценка за ответ: 5

Комментарий к оценке: Спасибо за информацию.

Мини-форум вопроса

Всего сообщений: 5; последнее сообщение — 29 ноября 2011, 00:51; участников в обсуждении: 4.
min@y™

min@y™ (статус: Доктор наук), 27 ноября 2011, 09:10 [#1]:

Цитата (Фамилия Имя Отчество):

не показывается никакой ошибки типа 'division by zero'?

Может компайлер просто выкинул эту операцию, т.к. переменная i больше не используется?
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
Фамилия Имя Отчество

Фамилия Имя Отчество (статус: Посетитель), 28 ноября 2011, 13:58 [#2]:

>>Может компайлер просто выкинул эту операцию, т.к. переменная i больше не используется?

procedure TForm1.Button1Click(Sender: TObject);
var
  a,b,c,d:real;
begin
  a:=0.0;
  b:=1.0;
  c:=b/a;
  d:=c;
end;

тоже не работает
Вадим К

Вадим К (статус: Академик), 28 ноября 2011, 14:48 [#3]:

это оптимизации.
Попробуйте написать так
procedure TForm1.Button1Click(Sender: TObject);
var
  a,b,c,d:real;
begin
  a:=0.0;
  b:=1.0;
  c:=b/a;
  d:=c;
  showmessage(floattostr(d));
end;
Галочка "подтверждения прочтения" - вселенское зло.
Толяныч

Толяныч (статус: 4-ый класс), 29 ноября 2011, 00:37 [#4]:

http://gaev.users.photofile.ru/photo/gaev/2123653/xlarge/207066901.jpg?

Все работает - и в среде под отладчиком, и автономно. Может, у Вас не Delphi ?
Фамилия Имя Отчество

Фамилия Имя Отчество (статус: Посетитель), 29 ноября 2011, 00:51 [#5]:

Вариант, подсказанный Вадимом работает!
Спасибо.

9 декабря 2011, 14:42: Статус вопроса изменён на решённый (изменил автор вопроса — Фамилия Имя Отчество): Ура! Мне дали награду за лучший вопрос месяца! Надо отметить!

Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.

Версия движка: 2.6+ (26.01.2011)
Текущее время: 16 ноября 2024, 15:40
Выполнено за 0.04 сек.