Floating point division by zero delphi ошибка

I just tried the following code:

procedure TTTest.FormCreate(Sender: TObject);
var v: extended;
    one: extended;
begin
  one := 1.0;
  v := 100*Power(1.25,one);
end;

It just compiles and runs as expected in Delphi 5.

My guess is that the division per zero flag may be set outside your code (even if you do not link to C++ code, calling Direct X or such may have the same effect), but raised later, in _Frac.

The only call to Frac in the standard implementation of Power() is to test Frac(Exponent) = 0.0.

There was a modification in the implementation of Frac between Delphi 5 and Delphi 6.

Here is the Delphi 5 version:

procedure       _FRAC;
asm
    FLD     ST(0)
    SUB     ESP,4
    FSTCW   [ESP]
    FWAIT
    FLDCW   cwChop
    FRNDINT
    FWAIT
    FLDCW   [ESP]
    ADD     ESP,4
    FSUB
end;

Here is the Delphi 6 version:

procedure       _FRAC;
asm
    FLD     ST(0)
    SUB     ESP,4
    FNSTCW  [ESP].Word     // save
    FNSTCW  [ESP+2].Word   // scratch
    FWAIT
    OR      [ESP+2].Word, $0F00  // trunc toward zero, full precision
    FLDCW   [ESP+2].Word
    FRNDINT
    FWAIT
    FLDCW   [ESP].Word
    ADD     ESP,4
    FSUB
end;

From the above code, you’ll find out that the following commands caused the delayed exceptions to be raised before Delphi 6 was released: Trunc, Frac, Ceil.

So I guess you faced an issue with Delphi 5, which has been fixed with Delphi 6. You may have to use your own version of Power, like this one:

function Power(Base, Exponent: Extended): Extended;
begin
  if Exponent = 0.0 then
    Result := 1.0               { n**0 = 1 }
  else if (Base = 0.0) and (Exponent > 0.0) then
    Result := 0.0               { 0**n = 0, n > 0 }
  else
    Result := Exp(Exponent * Ln(Base))
end;

Всем привет дорогие читатели блога, а самое главное, любители MapWindow GIS и вообще, любых других геоинформационных систем. Я обещал, что буду постепенно публиковать  материал  по новой версии MapWindow GIS, поэтому данная небольшая статья для решения одной проблемы с новой версии.

Мне уже задавали этот вопрос, а именно, что когда устанавливают компонент TMap на свою форму, а затем просто при компиляции проекта появляется ошибка: floating point division by zero. Если честно, то я не знаю, в какой момент она возникает. Может это связано с системой координат, либо еще что-то, но решается она очень и очень просто, по крайней мере, я так ее решил. Эту ошибку я наблюдал в Delphi 7, что касается других версий Delphi, я сказать ничего не могу, поэтому ее может просто и не быть.

Поэтому, если после обновления MapWindow GIS до версии 4.9.1 или 4.9.2 у Вас появляется подобная ошибка, то ниже будет описано, как ее можно решить. Мы просто отключим исключения, которые возникают с использованием чисел с плавающей точкой.

Для начала нам нужно объявить константу:

const MCW_EM = DWord($133f);

А затем на событие OnCreate формы, либо можно OnShow пишем следующий код:

Вот и все, как видите, ничего сложного. Теперь нам необходимо просто установить компонент на форму и скомпилировать проект. У меня такой ошибки больше не появляется, и программа отрабатывает на 100 процентов.

Ошибка «floating point division by zero» возникает в Delphi, когда в программе происходит деление на ноль с плавающей точкой. Она возникает из-за особенностей работы процессора с плавающей точкой и может привести к неожиданным результатам вычислений.

Чтобы избежать данной ошибки, можно добавить проверку на ноль перед выполнением операции деления. Для этого можно использовать условную конструкцию if, например:

if B <> 0 then
Result := A / B
else
Result := 0;

В данном коде мы проверяем, не равен ли знаменатель B нулю, и только в этом случае выполняем операцию деления. Если же B равен нулю, то возвращаем ноль.

Также возможны случаи, когда ошибка «floating point division by zero» возникает неочевидно, например, при вычислении математических функций, которые зависят от деления. В этом случае можно использовать специальные функции, например:

function ArcTan2(Y, X: Double): Double;
begin
if X = 0 then begin
if Y > 0 then Result := Pi / 2
else if Y < 0 then Result := -Pi / 2
else Result := 0;
end
else Result := ArcTan(Y / X);
end;

Функция ArcTan2 вычисляет арктангенс Y/X, но при этом учитывает особенности работы с плавающей точкой. Если знаменатель X равен нулю, то функция возвращает корректный результат в зависимости от знака числа Y.

PYTHON : Error python : [ZeroDivisionError: division by zero]

C++ : On which platforms does integer divide by zero trigger a floating point exception?

C++ : Error 83 error C2398: conversion from ‘double’ to ‘float’ requires a narrowing conversion

Fix invalid floating point error

Cara Memperbaiki Object di Form Yang Error — division by zero delphi

C++ : The behaviour of floating point division by zero

C++ : Floating Point, is an equality comparison enough to prevent division by zero?

Fix — Invalid Floating Point State Error in Windows 10

Binary 4 – Floating Point Binary Fractions 1

 
Kudatsky
 
(2002-07-22 10:13)
[0]

Delphi 5 не реагирует на ошибки с плавающей точкой.

Например:

procedure TForm2.Button1Click(Sender: TObject);

Var

A,B,C:Double;

begin

Try

A:=0;

B:=1;

C:=B/A;

Caption:=FloatToStr(C);

Except

Caption:=»Ошибка»;

end;

end;

В этом примере управление не попадает в Except, а в

Caption выводится «INF».

Похоже, что-то с отладчиком ?


 
IlyaA
 
(2002-07-22 10:25)
[1]

Посмотри в доке параметры компиляции. Там есть параметр. Ругаться или нет.


 
IlyaA
 
(2002-07-22 10:26)
[2]

А с отладчиком всё в порядке. Ошибка в коде (
ГЕНЕТИЧЕСКОМ).

ИЗВИНИ. Злая шутка вырвалась наружу


 
VICTOR_
 
(2002-07-22 10:31)
[3]

Прверил, у меня Except обрабатывается. Попробуй поставить break-point на B:=1; и сделать трассировку(F7)


 
kudatsky
 
(2002-07-22 10:37)
[4]

За шутку извиню. Но только если подскажешь, какой папаметр.

Иначе буду являться по ночам угрызениями совести ;-)))


 
kudatsky
 
(2002-07-22 10:45)
[5]

Кое-что нашёл.

Если снять флажок «Integration debugging»,

Except обрабатывается.

Но в варианте

A:=0;

B:=1;

C:=B/A;

Caption:=FloatToStr(C);

появляется сообщение «Floating point division by zero», а

остановки на строке с ошибкой не происходит


 
Skier
 
(2002-07-22 11:30)
[6]

>kudatsky

Debbuger Options|Language Exceptions|Stop on Delphi Exceptions ?


 
kudatsky
 
(2002-07-22 11:44)
[7]

Опция

Debbuger Options|Language Exceptions|Stop on Delphi Exceptions

включена


 
Skier
 
(2002-07-22 11:50)
[8]

>kudatsky

Debbuger Options|General|Integrated debugging := True


 
kudatsky
 
(2002-07-22 11:56)
[9]

Опция Integrated debugging включена.


 
Skier
 
(2002-07-22 11:57)
[10]

>kudatsky

И что ? На C:=B/A; не останавливается ?


 
kudatsky
 
(2002-07-22 12:02)
[11]

Не останавливается.

В Caption выводится «INF»

Может что на страницах OS Exception или Language Exception ?


 
Skier
 
(2002-07-22 12:08)
[12]

>kudatsky

У тебя в списке Exceptions на странице OS Exception есть

Float Devide By Zero ?


 
Viewer
 
(2002-07-22 12:10)
[13]

INF — infinity (так Борланд реагирует на эти шутки)


 
kudatsky
 
(2002-07-22 12:11)
[14]

Есть.

User program:=true

Run unhandled:=true


 
IlyaA
 
(2002-07-22 13:07)
[15]

В блоке try-except попробуй-

try

a:=b/0;

except

on EDivByZero do ShowMessage(«Error»);

end;


 
kudatsky
 
(2002-07-22 13:43)
[16]

Сделал.

Исключение не возбуждается.


 
IlyaA
 
(2002-07-22 13:45)
[17]

Похоже у тебя уже всё
упало.


 
kudatsky
 
(2002-07-22 13:52)
[18]

Только-что инстолировал D5 на другую машину. То же самое. Что интересно, никакой реакции на

on E: Exception do ShowMessage(«Error»);

Может Delphi с глюками ?


 
Слесарь Матерящийся
 
(2002-07-22 13:59)
[19]

Может, дело в точности представления вещественного числа?

То есть, присваиваем чистый 0, а получаем 0 + погрешность, и в результате не-ноль.

Попробуйте то же самое с целыми числами.


 
IlyaA
 
(2002-07-22 14:01)
[20]

Вот енто из хэлпы. Может что и прояснит

EIntError is the base class for integer math error exceptions.

Unit

SysUtils

Description

EIntError is a generic integer math exception. Although it is never raised in the runtime library, it is the base from which other integer math exceptions descend. These are the integer math exceptions:

Exception Meaning

EDivByZero An attempt was made to divide by zero

ERangeError Number or expression out of range

EIntOverflow Integer operation overflowed

Run-time exception information is saved in fields provided by EExternal.


 
kudatsky
 
(2002-07-22 14:02)
[21]

С целыми числами всё в порядке, я уже пробовал.


 
Слесарь Матерящийся
 
(2002-07-22 15:11)
[22]

То-то и оно!


 
kudatsky
 
(2002-07-22 15:19)
[23]

????????????????


 
tall
 
(2002-07-22 16:00)
[24]

Я эту тему пеоднимал уже несколько раз. Кстати и в этой конфе тоже. Куда только не писал. Вразумительный ответ дали только в AMD (у меня эти глюки начались после того как пересел с Pentium 200MMX на AMD 1200. Думал может связано сплатформой). Там мне сказали, что это не глюк, а изменения в компиляторе в соответствии с требованиями новых стандартов ( типа ответ +INF или -INF (бесконечность) и тому подобное это не исключительная ситуация а нормальное явление). И отослели к технической документации по процессору( там, кстати, это действительно написано). Судя по всему это относится и Pentium платформе (мне писали об аналогичных проблемах на Celeron), т.е. характерно для всех новых процессоров. Решить эту проблему удалось только откатившись на DELPHI 4. Чего и вам советую.


 
kudatsky
 
(2002-07-23 10:27)
[25]

tall, если Вы ещё здесь!

Где это можно прочитать ?


 
VICTOR_
 
(2002-07-23 11:48)
[26]

У тебя материнка на VIA логике?


 
Viewer
 
(2002-07-23 12:24)
[27]

ffmt.asm

; INF and NAN strings

INFNAN DB «INFNAN»

; function FloatToText(Buffer: PChar; const Value; ValueType: TFloatValue;

; Format: TFloatFormat; Precision, Digits: Integer): Integer;

sysutils.pas

function TextToFloat(Buffer: PChar; var Value;

ValueType: TFloatValue): Boolean;

{ FloatToDecimal converts a floating-point value to a decimal representation

that is suited for further formatting. The Value parameter must be a

variable of type Extended or Currency, as indicated by the ValueType

parameter. For values of type Extended, the Precision parameter specifies

the requested number of significant digits in the result—the allowed range

is 1..18. For values of type Currency, the Precision parameter is ignored,

and the implied precision of the conversion is 19 digits. The Decimals

parameter specifies the requested maximum number of digits to the left of

the decimal point in the result. Precision and Decimals together control

how the result is rounded. To produce a result that always has a given

number of significant digits regardless of the magnitude of the number,

specify 9999 for the Decimals parameter. The result of the conversion is

stored in the specified TFloatRec record as follows:

Exponent — Contains the magnitude of the number, i.e. the number of

significant digits to the right of the decimal point. The Exponent field

is negative if the absolute value of the number is less than one. If the

number is a NAN (not-a-number), Exponent is set to -32768. If the number

is INF or -INF (positive or negative infinity), Exponent is set to 32767.

Negative — True if the number is negative, False if the number is zero

or positive.

Digits — Contains up to 18 (for type Extended) or 19 (for type Currency)

significant digits followed by a null terminator. The implied decimal

point (if any) is not stored in Digits. Trailing zeros are removed, and

if the resulting number is zero, NAN, or INF, Digits contains nothing but

the null terminator. }


уважаемые посетители блога, если Вам понравилась, то, пожалуйста, помогите автору с лечением. Подробности тут.

Наконец-то! Свершилось чудо! Наконец-то поймался тот самый «Floating point divizion by zero» о котором мне твердили несколько человек с тех самых пор, как я выложил первую версию клиента для DelphiFeeds.ru. Знаете, я бы никогда и ни за что не поверил в то, что когда-нибудь буду радоваться пойманному в своей собственной программе багу…Серьезно. Пытался найти эту ошибку всякими разными способами — таскал программу на работу, проверял на всех подряд компах — нет ошибки! А всего-то надо было…сесть за компьютер жены и запустить программу там и…

Вот он родимый «Floating point divizion by zero» как есть. 

Надо сказать, до последнего момента пока не посмотрел отчёт MadExcept относительно этой ошибки, я сомневался: то ли этот баг конкретно мой (хотя никаких делений в программе, в принципе нету), то ли сам стиль глючит. А вот, что мне выдал MadExcept после того как я создал новый проект с Jet Style внутри:

00a374dc +080 Project8.exe  FMX.Types        8459 +7   TCanvas.CreateFromBitmap
009b6fdf +01b Project8.exe  FMX.Canvas.D2D   688 +1    TCanvasD2D.CreateFromBitmap
00a36f96 +016 Project8.exe  FMX.Types        8345 +1   TCanvasManager.CreateFromBitmap
00a3165e +01a Project8.exe  FMX.Types        6796 +3   TBitmap.GetCanvas
009d6771 +321 Project8.exe  FMX.Platform.Win 1889 +50  TWindowBorderWin.InvalidateRegion
009d6ed2 +06e Project8.exe  FMX.Platform.Win 2001 +10  TWindowBorderWin.RecreateRegion
009d8964 +d84 Project8.exe  FMX.Platform.Win 2411 +138 WMNCMessages
009d9484 +618 Project8.exe  FMX.Platform.Win 2684 +136 WndProc
774b0107 +02b ntdll.dll KiUserCallbackDispatcher
00a73a93 +053 Project8.exe  FMX.Forms        3077 +6   TCommonCustomForm.SetWindowState
00a70103 +017 Project8.exe  FMX.Forms        1742 +1   TWindowBorder.DoMinClick
00a47791 +17d Project8.exe  FMX.Types        13319 +28 TControl.Click
0098d21a +04a Project8.exe  FMX.Controls     2468 +14  TCustomButton.Click
00a47cfe +096 Project8.exe  FMX.Types        13424 +7  TControl.MouseUp
0098d46f +073 Project8.exe  FMX.Controls     2529 +13  TCustomButton.MouseUp
00a70664 +074 Project8.exe  FMX.Forms        1857 +4   TWindowBorder.MouseUp
009d88ae +cce Project8.exe  FMX.Platform.Win 2379 +106 WMNCMessages
009d9585 +719 Project8.exe  FMX.Platform.Win 2710 +162 WndProc
75f87885 +00a USER32.dll DispatchMessageW
009d1b99 +039 Project8.exe  FMX.Platform.Win 487 +8    TPlatformWin.HandleMessage
00a6c0c6 +042 Project8.exe  FMX.Forms        1328 +3   TApplication.HandleMessage
009d1b0f +02b Project8.exe  FMX.Platform.Win 464 +4    TPlatformWin.Run
00a6f486 +0da Project8.exe  FMX.Forms        1473 +12  TApplication.Run
00a9ede3 +03b Project8.exe  Project8         17 +3     initialization
74d733a8 +010 kernel32.dll  BaseThreadInitThunk

После этого отчета мое состояние можно было бы описать примерно так:

Приложение, которое выглядит вот так:

оказалось виновато в том, что оно вообще запустилось (TApplication.Run) и пользователь ткнул мышкой куда-то по форме (куда-то — это на кнопочку минимизации окна). При этом, обращу внимание на тот факт, что демка, идущая в комплекте со стилем работает без ошибок :) И «секрет» крылся в том, что демо-приложение Embarcadero выглядело вот так:

Т.е свойство EnableBorderStyle было выставлено как False. Стоит его вернуть в True и «Floating point divizion by zero» выскакивает аки чёрт из табакерки. Итак место ошибки было более менее определено — бордюры окна, а точнее стилизованные бордюры окна. Просмотрел стиль на наличие или отсутствие каких-либо элементов бордюра — вроде бы все в норме, размеры TRect’ов выставлены правильно, положение элементов тоже. Полез снова в отчет, начал ковыряться в исходнике FMX и обнаружил место где конкретно срабатывает Exception:

//FMX.Canvas.GDIP.pas
constructor TCanvasGdiPlus.CreateFromBitmap(const ABitmap: TBitmap);
begin
  inherited CreateFromBitmap(ABitmap);
  FGPGraphics := TGPGraphics.Create(TGPBitmap(FBitmap.Handle));
  FGPGraphics.SetSmoothingMode(SmothingDefault);
  FGPGraphics.SetPixelOffsetMode(PixelOffsetModeHalf);
  FGPGraphics.SetInterpolationMode(InterpolationModeHighQuality);
  FGPGraphics.SetTextContrast(TextContrast);
  if GlobalUseGDIPlusClearType then
    FGPGraphics.SetTextRenderingHint(TextRenderingHintClearTypeGridFit)
  else
    FGPGraphics.SetTextRenderingHint(TextRenderingHintAntiAlias);
  FGPPen := TGPPen.Create($FF000000);
  FGPPenBrush := TGPSolidBrush.Create($FF000000);
  FGPBrush := TGPSolidBrush.Create($FFFFFFFF);
  FGPFamily := TGPFontFamily.Create('Tahoma');
  FFontScale := 96 / FGPGraphics.GetDpiX; //ВОТ ТУТ FGPGraphics.GetDpiX = 0

Почему так происходит и когда вызывается этот самый конструктор, скажу откровенно, особенно не искал и в обозримом будущем не планирую — на то есть специально обученные люди. Факт наличия бага есть, баг хоть и не всегда, но воспроизводим. Вполне возможно, что зависит он от видюшки, т.к. у меня стоит ATI Radeon, а у жены на компе — NVidia. Точное место откуда вываливается злосчастный «Floating point divizion by zero» указано. Накорябал баг-репорт…но что-то я его не наблюдаю в этом списке, поэтому, если что — баг остается «вакантным» — можете отправить его в QC повторно :) Пока же, для тех, кто хочет использовать Jet Style в своих приложениях, небольшой совет:

Не ставьте у приложения с Jet Style свойство формы EnableBorderStyle в значение True — избавите и себя и пользователей от лишнего бага

А я тем временем поисправляю кой-чего в клиенте DelphiFedds.ru, кстати там введена регистрация пользователей, так что скоро нас все посчитают :) Всем удачи и до новых встреч!

Update. Баг-репорт с описанием ошибки опубликован.  Кто встречался с этой ошибкой — голосуйте

Скачать программу можно на форуме.

0
0
голоса

Рейтинг статьи

уважаемые посетители блога, если Вам понравилась, то, пожалуйста, помогите автору с лечением. Подробности тут.

Понравилась статья? Поделить с друзьями:
  • Float object is not iterable python ошибка
  • Float object is not callable ошибка
  • Filezilla выдает критическую ошибку
  • Filezilla ошибка 110
  • Filezilla невозможно подключиться к серверу ps3 ошибка