ДЕление на 0 в DELPHI 2007
, Почему не выскакивает ошибка ?
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
| ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
| [216.73.216.143] |
|
|
ПРАВИЛА РАЗДЕЛА · FAQ раздела Delphi · Книги по Delphi
ДЕление на 0 в DELPHI 2007
, Почему не выскакивает ошибка ?
|
Сообщ.
#1
,
|
|
|
|
![]() ![]() procedure TForm8.FormCreate(Sender: TObject); var d:Double; begin d := 12/0; d:=d*2; Self.Tag := Trunc(D*2);//Ошибка вылетает только здесь, но по идее должна же вылетать на делении end; В инете находил инфу только по констатации факта, что для того, чтобы было корректно и вылетала ошибка, шужно делать через переменную. ![]() ![]() procedure TForm8.FormCreate(Sender: TObject); var d,с:Double; begin с := 12; d := c/0; d:=d*2; Self.Tag := Trunc(D*2);//Ошибка вылетает только здесь, но по идее должна же вылетать на делении end; Вот так ошибка уже не вылетает. ВОпрос. МОжно ли в настройках дельфи сделать так, чтобы ошибку выдавалобез переменной С сразу при делении 12 на 0? |
|
Сообщ.
#2
,
|
|
|
|
Гм, может я не прав, но при чем тут Делфи вообще?
Ошибка деления на 0 возникает только для целых типов. У вас же - Double. Там никаких ошибок быть не может т.к. результат деления на 0 - Inf (специальное значение для форматов с плавающей запятой. Еще есть NaN). |
|
Сообщ.
#3
,
|
|
|
|
Цитата Marriage @ МОжно ли в настройках дельфи сделать так, чтобы ошибку выдавало без переменной С сразу при делении 12 на 0? Видимо нет, т.к. компилятор воспринимает константное выражение d:=12/0 как "осознанное" присвоение переменной d значения Infinity, вполне допустимое для вещественных чисел. Соотв-но встречая 12/0 компилятор ничего не делит, а просто заменяет деление присвоением d:=Infinity Цитата Chow @ Ошибка деления на 0 возникает только для целых типов. У вас же - Double. Там никаких ошибок быть не может т.к. результат деления на 0 - Inf С поправкой, что это относится только к константам, т.к. при явном делении в рантайме d:=c/0 ошибка EZeroDivide ес-но возникает (если ее специально не маскировать вызовом SetExceptionMask) |
|
Сообщ.
#4
,
|
|
|
|
все гораздо проще... компилятор оптимизирует строчки:
![]() ![]() d := 12/0; d:=d*2; Self.Tag := Trunc(D*2); ![]() ![]() Self.Tag := Trunc((12/0)*2*2); может даже быть так, что переменная в опертивной памяти не наблюдается |
|
Сообщ.
#5
,
|
|
|
|
Цитата SPrograMMer @ все гораздо проще... А что проще то ? По любому при наличии в константном выражении деления на 0 компилятор заменяет все выражение на Infinity, которое для процессора является вполне легальным значением и соотв-но ни его загрузка в FPU, ни умножения\деления и т.п. на конечные значения не вызывают никаких исключений. Поэтому независимо от того соптимизирует компилятор вычисления или нет, ошибка тут будет не EZeroDivide, а EInvalidOp при попытке преобразовать Infinity к целому числу через Trunc |