Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Invalid floating point operation (https://www.delphipraxis.net/96827-invalid-floating-point-operation.html)

daschaos 31. Jul 2007 13:17


Invalid floating point operation
 
Hallo...

Es tut mit leid, dass ich hier soviel Quellcode posten muss, aber ich weiß einfach nich woran es liegt. Mein Programm stürzt einfach irgendwann ab, wenn ich das Fenster verkleinern will, ab einer bestimmten Größe schmiert er ab und alles hängt sich auf. Es kam irgendwann ma die oben genannte Fehlermeldung. Ich weiß mir nich so richtig zu helfen. Wäre toll, wenn einer mal drüber schauen könnte bzw. generell eine Idee hätte, worans liegen könnte...Dachte eiegntlich ich würd alles soweit beachten.

Dankeschön schonmal und liebe Grüße,
Laura

Delphi-Quellcode:
procedure CalculateRect(ParentID: TTreemapElementID; ARect: TRect; Layer: Integer;
  CalculateHint: Boolean; MouseX: Integer; MouseY: Integer; var Path: WideString; var FrameRect: TRect;
  var Caption: WideString; var Value: Integer; var ID: TTreemapElementID);
var
  i: Integer;
  ChildCount: Integer;
  StartIndex: Integer;
  EndIndex: Integer;
  Orientation: Boolean;
  CurrentAspect: Single;
  LastAspect: Single;
  CurrentX: Single;
  CurrentY: Single;
  CurrentX1: Single;
  CurrentY1: Single;
  OffsetX: Single;
  OffsetY: Single;
  TotalSum: Integer;
  ScaleValue: Double;
  TempChildCount: Integer;
  AWidth: Integer;
  AHeight: Integer;
  TempWidth: Single;
  TempHeight: Single;
  TempArray: Array of TSortArray;
  j: Integer;
begin
  StartIndex := 0;
  EndIndex := 0;
  CurrentAspect := 999;
  OffsetX := 0.0;
  OffsetY := 0.0;
  AWidth := ARect.BottomRight.X - ARect.TopLeft.X;
  AHeight := ARect.BottomRight.Y - ARect.TopLeft.Y;
  TempWidth := AWidth;
  TempHeight := AHeight;

  // keine Gleitkommazahlberechnungen, daher nich wichtig
  Orientation := DrawingOrientation(TempWidth, TempHeight);
  ComputeSizeArray(ParentID);
  ChildCount := DoGetChildCount(ParentID);
  TotalSum := SumRectangles(ParentID);

  try
    ScaleValue := ((AWidth * AHeight) / TotalSum) / 100
  except
    on EZeroDivide do
      ScaleValue := 0.0;
  end;
  for i := 0 to ChildCount-1 do
  begin
    SortArray[i].SizeTemp := ScaleValue * SortArray[i].Values.ChildValue;
  end;
  while (EndIndex <> ChildCount) do
  begin
    LastAspect := SquarifiedTryLayout(StartIndex, EndIndex, Orientation, TempWidth, TempHeight);
    if ((LastAspect > CurrentAspect) or (LastAspect < 1)) then
    begin
      CurrentX := ARect.TopLeft.X;
      CurrentY := ARect.TopLeft.Y;
      for i:= StartIndex to EndIndex-1 do
      begin
        SortArray[i].X := OffsetX + CurrentX;
        SortArray[i].Y := OffsetY + CurrentY;
        if (Orientation)then
          CurrentY := Single(CurrentY) + Single(SortArray[i].Height)
        else
          CurrentX := Single(CurrentX) + Single(SortArray[i].Width);
      end;//for
      if (Orientation) then
        OffsetX := Single(OffsetX) + Single(SortArray[StartIndex].Width)
      else
        OffsetY := Single(OffsetY) + Single(SortArray[StartIndex].Height);
      TempWidth := AWidth - OffsetX;
      TempHeight := AHeight - OffsetY;
      Orientation := DrawingOrientation(TempWidth, TempHeight);
      StartIndex := EndIndex;
      EndIndex := StartIndex;
      CurrentAspect := 999;
      continue;
    end//if(LastAspect>CurrentAspect)
    else
    begin
      for i:= StartIndex to EndIndex do
      begin
        SortArray[i].Width := SortArray[i].TempWidth;
        SortArray[i].Height := SortArray[i].TempHeight;
      end;//for
      CurrentAspect := LastAspect;
    end;//else
    EndIndex := EndIndex + 1;
  end;//while(EndIndex <> ChildCount)
  CurrentX1 := ARect.TopLeft.X;
  CurrentY1 := ARect.TopLeft.Y;
  for i:= StartIndex to EndIndex-1 do
  begin
    SortArray[i].X := Single(OffsetX) + Single(CurrentX1);
    SortArray[i].Y := Single(OffsetY) + Single(CurrentY1);
    if (Orientation) then
      CurrentY1 := CurrentY1 + SortArray[i].Height
    else
      CurrentX1 := CurrentX1 + SortArray[i].Width;
  end;//for
  if(CalculateHint = False) then
    SquarifiedPaintRect(Layer, ParentID)
  else
  begin
    for i:=0 to ChildCount-1 do
    begin
      ARect.TopLeft := Point(Round(SortArray[i].X), Round(SortArray[i].Y));
      ARect.BottomRight := Point(Round(SortArray[i].Width + SortArray[i].X), Round(SortArray[i].Height + SortArray[i].Y));
      if (CheckMouseMove(MouseX, MouseY, ARect, Path, ParentID, i)) then
      begin
        if ((ComputeArea(ARect) <= MinimumSize) or
          ((ShowLeafs = False) and (SortArray[i].Values.IsFolder = False))) then
        begin
          FrameRect.TopLeft := Point(0,0);
          FrameRect.BottomRight := Point(0,0);
          Value := 0;
        end
        else
        begin
          FrameRect := ARect;
          Caption := SortArray[i].Values.ChildCaption;
          Value := SortArray[i].Values.ChildValue;
          ID := SortArray[i].ChildID;
        end;//else
        exit;
      end;//if(CheckMouseMove)
    end;//for
  end;//if(CalculateHint)
  SetLength(TempArray, Length(SortArray));
  for j := 0 to Length(SortArray) - 1 do
  begin
    TempArray[j] := SortArray[j];
  end;
  for i := 0 to ChildCount-1 do
  begin
    TempChildCount := DoGetChildCount(TempArray[i].ChildID);
    if (TempChildCount >=1) then
    begin
      ARect.TopLeft := Point(Round(TempArray[i].X), Round(TempArray[i].Y));
      ARect.BottomRight := Point(Round(TempArray[i].Width + TempArray[i].X), Round(TempArray[i].Height + TempArray[i].Y));
      if (Parents) then
        AddPadding(ARect);
      DrawOuterRect(ARect, Layer+1, True, 2, SortArray[i].Values.ChildImageIndex, SortArray[i].Values.ChildCaption);
      SquarifiedCalculateRect(TempArray[i].ChildID, ARect, Layer+1, CalculateHint, MouseX, MouseY, Path, FrameRect, Caption,
        Value, ID);
    end;//if(TempChildCount...)
  end;//for
end;
Delphi-Quellcode:
function TCustomTreemapChart.SquarifiedTryLayout(StartIndex: Integer; EndIndex: Integer; Orientation: Boolean; TempWidth: Single;
  TempHeight: Single): Single;
var
  Total: Single;
  Aspect: Single;
  LocalWidth: Single;
  LocalHeight: Single;
  i: Integer;
begin
  Aspect := 0.0;
  Total := SumRectanglesIndex(StartIndex, EndIndex);
  if (Orientation) then
  begin
    try
      LocalWidth := Total / TempHeight * 100;
    except
      on EZeroDivide do
        LocalWidth := 0.0;
    end;
    LocalHeight := TempHeight;
  end//if(Orientation)
  else
  begin
    try
      LocalHeight := Total / TempWidth * 100;
    except
      on EZeroDivide do
        LocalHeight := 0.0;
    end;
    LocalWidth := TempWidth;
  end;//else
  for i:= StartIndex to EndIndex do
  begin
    if (Orientation) then
    begin
      SortArray[i].TempWidth := LocalWidth;
      try
        SortArray[i].TempHeight := Single(LocalHeight) * (Single(SortArray[i].SizeTemp) / Total);
      except
        on EZeroDivide do
          SortArray[i].TempHeight := 0.0;
      end;
    end//if(Orientation)
    else
    begin
      SortArray[i].TempHeight := LocalHeight;
      try
        SortArray[i].TempWidth := Single(LocalWidth) * (Single(SortArray[i].SizeTemp) / Total);
      except
      on EZeroDivide do
        SortArray[i].TempWidth := 0.0;
     end;
    end;//else
    Aspect := AspectRatio(SortArray[i].TempWidth, SortArray[i].TempHeight);
  end;//for
  Result := Aspect;
end;
Delphi-Quellcode:
function TCustomTreemapChart.SumRectanglesIndex(StartIndex: Integer; EndIndex: Integer): Single;
var
  i: Integer;
begin
  Result := 0.0;
  for i:= StartIndex to EndIndex do
  begin
    try
      Result := Single(Result) + Single(SortArray[i].SizeTemp);
    except
      on EAccessViolation do
        Result := 0.0;
    end;//try
  end;//for
end;
Delphi-Quellcode:
class function TCustomTreemapChart.AspectRatio(Width: Single; Height: Single): Single;
begin
  Result := 0.0;
  if ((Width > 0.0) and (Height > 0.0)) then
    Result := Max(Single(Width)/Single(Height), Single(Height)/Single(Width));
end;

SirThornberry 31. Jul 2007 14:13

Re: Invalid floating point operation
 
An welcher Stelle genau kommt der Fehler (welche Zeile/Anweisung). Teilst du eventuell irgendwo durch 0?

daschaos 31. Jul 2007 14:37

Re: Invalid floating point operation
 
Das ist ja leider das Problem, er stürzt komplett ab, dass er mir garkeine Stelle mehr nennt, an der Probleme aufgetreten sind. Deswegen bin ich ja so hilflos :(. Ich weiß nich, woran es liegt. Ich dachte, die Division durch Null hätte ich eigentlich überall abgefangen...

SirThornberry 31. Jul 2007 14:38

Re: Invalid floating point operation
 
du lässt das ganze in der IDE laufen und er stürzt ab ohne an einer bestimmten Stelle zu halten? Sowas hatte ich eigentlich bisher nur bei einem Stackoverflow.

daschaos 31. Jul 2007 14:46

Re: Invalid floating point operation
 
Ja, genau das passiert, okay, was kann denn alles einen StackOverlow auslösen?

SirThornberry 31. Jul 2007 14:54

Re: Invalid floating point operation
 
Du könntest erstmal eingrenzen wo er abschmiert in dem du alle paar zeilen eine Ausgabe in eine Datei oder ein anderes Programm machst. Dann siehst du was die letzte Ausgabe vor dem Absturz war. Wenn du dann weißt zwischen welchen 2 Ausgaben es also abgestürzt ist kannst du in diesem Bereich noch mehr Ausgaben einbauen um die genaue Zeile zu finden.

Zum Beispiel kannst du dafür OutputDebugString verwenden und als Anzeigeprogramm DebugView

FAlter 31. Jul 2007 14:56

Re: Invalid floating point operation
 
Hi,

bei einem Stacküberlauf liegt es meist daran, dass bei einer rekursiven function (oder procedure) irgendeine Abbruchbedingung nicht stimmt. Überprüf das mal.

Falls alles stimmt, versuch es mal, in den Projektoptionen die Stackgröße auf $00FFFFFF zu stellen, aber Achtung - falls es doch einen Fehler gibt, kommt es dann nach seeeeeeeeeeeeehr langer Zeit erst zu einem Stacküberlauf, nämlich, wenn die 16 MB voll sind. Meist sollte $0000FFFF ausreichen.

Mfg
FAlter(Im übrigen war es bei alten Delphiversionen möglich, den Stack größer als 16 MB zu machen - die Programme waren dann aber nicht auf 9x/ME lauffähig).

bitsetter 1. Aug 2007 00:23

Re: Invalid floating point operation
 
Hi,

wenn ich zum Beispiel sowas rechne, dann kommt bei mir die gleiche Fehlermeldung.
Delphi-Quellcode:
var
  s: single;
begin
  s:= 1111111111/ 0.0000000001;
  caption:= inttostr(trunc(s));
  //caption:= inttostr(round(s));
und so nicht:
Delphi-Quellcode:
var
  s: single;
begin
  s:= 1111111111/ 0.0000000001;
  caption:= floattostr(s);
Zitat:

Zitat von SirThornberry
du lässt das ganze in der IDE laufen und er stürzt ab ohne an einer bestimmten Stelle zu halten? Sowas hatte ich eigentlich bisher nur bei einem Stackoverflow.

Bei mir hält er dabei nirgendwo.

FAlter 1. Aug 2007 11:35

Re: Invalid floating point operation
 
Hi,

bei mir gibts zwar auch die Exception, aber dafür in einer Zeile.

Zum testen habe ich es nochmal aufgesplittet...

Delphi-Quellcode:
var
  s: single;
  I: Integer;
begin
  s:= 1111111111/ 0.0000000001;
  I := trunc(s); //<-- hier EInvalidOp (s = 1,1111111456e+19)
  caption:= inttostr(I);
end;
Hast du es mit Breakpoint setzen + F8 versucht?

Es liegt daran, dass S (immerhin 1,11 * 10^19) zu groß ist, um z. B. per Trunc in einen Integer umgewandelt werden zu können.

Bei mir wurde übrigens bei Applicatzion.Run (ohne Breakpoint+F8 ) gehalten - das ist nicht nirgendwo (und sogar korrekt :mrgreen: ).

Mfg
FAlter

bitsetter 1. Aug 2007 12:07

Re: Invalid floating point operation
 
Zitat:

Zitat von FAlter
Es liegt daran, dass S (immerhin 1,11 * 10^19) zu groß ist, um z. B. per Trunc in einen Integer umgewandelt werden zu können.

Hi,

das ist mir schon klar, dass es an Round oder Trunc liegt, das konnte man ja auch so sehen. Er benutzt aber Round und Single in seinem Code. Der Fehler scheint ja nur gelegentlich aufzutreten und da alles mit F8 durchzusteppen kann ganz schon schwierig sein.

Zitat:

Zitat von FAlter
Bei mir wurde übrigens bei Applicatzion.Run (ohne Breakpoint+F8 ) gehalten - das ist nicht nirgendwo (und sogar korrekt :mrgreen: ).

Ja wenn du den Code gleich beim Programmstart ausführst, das ist anscheinend hier nicht der Fall. Wenn ich den Code nicht gleich beim Start ausführe bleibt er aber nicht stehen.
Ich wollte damit nur sagen, dass es auch damit zusammenhängen kann, auch wenn dazu schon ziemlich lange Zahlen notwendig sind.


Alle Zeitangaben in WEZ +1. Es ist jetzt 23:20 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz