Possible SimpleGraph bug (well ExtGraph project bug)

Please post bug reports, feature requests, or any question regarding the DELPHI AREA products here.

Possible SimpleGraph bug (well ExtGraph project bug)

Postby Specto » March 27th, 2005, 9:08 pm

Hi register on the forum just to report this, so hope its not me being stupid.

I recently found need of a library to perform graphing, and stumbled across TSimpleGraph, and the ExtGraph project.
I have to say I am very impressed, however I did discover a small "bug" which you may wish to hear about.

I use the term "bug" loosely here because I am not sure if it is a code problem, or just a limitation of the types available.

I originally found the bug using a program I created which layed out about 320 nodes with about 1000 links programatically, and sometimes the nodes would be at coordinates such as 3020,3020, linked back to nodes at near 0,0.

Once the nodes have been inserted, and the links created, moving the mouse about over the canvas area of the TSimpleGraph usually caused an "EInvalidOP" error with message "Invalid Floating Point Operation"

I have attached an example program source code, and compiled executable all in ZIP format. Its a delphi 6 file so anything greater should read it. You need to have the TSimpleGraph component installed obviously.

You can recreate the bug, by using the following code:
Code: Select all
procedure test1:
var PR: PRect;
    R: TRect;
    N1: TGraphNode;
    N2: TGraphNode;
begin
   R.Left := 0;
   R.top := 0;
   R.Bottom := 20;
   R.Right := 20;
   PR := @R;
   N1 := SimpleGraph1.InsertNode(PR, TRoundRectangularNode);
   R.Left := 3020;
   R.top := 3020;
   R.Bottom := R.top + 20;
   R.Right := R.Left + 20;
   N2 := SimpleGraph1.InsertNode(PR, TRoundRectangularNode);
   SimpleGraph1.LinkNodes(N1, N2);
end;


Please note it is intermittent with this test code, you may wish to try moving both nodes about, and scrolling around, moving the mouse widely. I have found the following generally helps make it crash faster:
1) Scroll vertically and then horizontally to the bottom-right corner by dragging the peas in the scrollbars
2) Move the node there furthur away by about 200 pixels (exact amount unimportant) - thus expanding the canvas area
3) Scroll the bars to the bottom-right again to bring the node back into view (do this by clicking in the bar, rather than dragging the pea)
4) Scroll the horizontal bar back about halfway very quickly, and then move the mouse upwards over the canvas. Sometimes you must release the mouse as you move upwards, before you actually move over the canvas. This is the tricky bit


Once the program starts producing the errors when you move the mouse over the simplegraph canvas, it will keep doing it until the program is shut down.

I am using Borland Delphi 6.0 (Build 6.163) on W2k SP3.

I spent some time (several hours) tracking this down, and found it to be in the v1.542 (oct 12th) build of SimpleGraph.pas:980 DistanceToLine routine:

Code: Select all
 Result := Round(Sqrt(Sqr(QueryPt.X - Pt.X) + Sqr(QueryPt.Y - Pt.Y)));


The reason for this error? Well value inspection reveals the following:
QueryPt.X := 219;
QueryPt.Y := 3;
Pt.X := -90372;
Pt.Y := -88337;

These values vary from run to run - but the critical point is the X, Y values for "Pt" are somewhere around -80000 (although I have had it occur with values of -40000).

This causes the Sqrt command to produce the EInvalidOP error (invalid floating point operation).

I broke the issue down into a standalone procedure:

Code: Select all
procedure test();
var ResultInt : integer;
    QueryPt   : TPoint;
    Pt        : TPoint;
    X         : integer;
    Y         : integer;
    Squared1  : Extended;
    Squared2  : Extended;
    Squared   : Extended;
    Sqroot    : Extended;
begin
{sqr(-83126) + sqr(-80755)
6909931876 + 6521370025
sqrt(13431301901)
115893.4938}
  QueryPt.X := 219;
  Pt.X := -90372;
  QueryPt.Y := 3;
  Pt.Y := -88337;
  X := QueryPt.X - Pt.X;
  Y := QueryPt.Y - Pt.Y;
  Squared1 := Sqr(X);
  Squared2 := Sqr(Y);
  Squared := Squared1 + Squared2;
  sqroot := Sqrt(Squared);
  ResultInt := Round(sqroot);
  ShowMessage(IntToStr(ResultInt));
end;


Interestingly if I change the variable types as follows:
Code: Select all
  X         : Extended;
    Y         : Extended;


You no longer get the error message.

I am not sure what is going on here - I suspect a simple overflow, but then surely changing those two variables to extended should not have any effect (especially since the error occurs after those values have been calculated and written back).

Am I actually using the InsertNode and LinkNodes routines correctly, or do I need to use new to create a new version of TRect for the first parameter to point to each time?

Anyway, hope this is not something serious cause I'd like to get my program working a bit more stably.

Any ideas?
Specto
Member
Member
 
Posts: 2
Joined: March 27th, 2005, 8:53 pm

Postby Stefan » March 29th, 2005, 1:06 pm

Hi,

I am not sure what is going on here - I suspect a simple overflow, but then surely changing those two variables to extended should not have any effect (especially since the error occurs after those values have been calculated and written back).


In a nutshell:

Sqrt() isn't the problem, Sqr() is.

Sqr() returns the same type as it is given (in this case, Integer) this is done without any range-checking. So this will fail if the Integer passed to Sqr() is too large (it's too large when the Sqr() of the Integer overflows the 32 bits the resulting integer can hold, as there's no range checking).

Subsequently assigning that bad Integer to an Extended doesn't make things better.

So to get an Extended value from Sqr() you must pass it an Extended variable and changing those variables' types does indeed have (a rather good) effect :)

Cheers,
Stefan
User avatar
Stefan
Moderator
Moderator
 
Posts: 128
Joined: September 27th, 2004, 9:40 am
Location: Tilburg, The Netherlands

Postby Specto » April 1st, 2005, 7:57 pm

Sorry for the late reply!
Ah of course that makes sense - sqr is just an overloaded function!

Are you planning on fixing this in a future release? At least to catch the error and handle it in a more user friendly manner?

I have modified my version to use the extended type for now, which will slow it down some, but considering the number of nodes and interconnections being used in this project the user won't notice it getting any slower.

(I am visualising friends between users on a blog site I am a member of - luckily it is one of the smaller communities, but still a few thousand members, and even more friends).
As you can imagine getting things layed out nicely is a bit tricky.
Specto
Member
Member
 
Posts: 2
Joined: March 27th, 2005, 8:53 pm


Return to DELPHI AREA Products

Who is online

Users browsing this forum: No registered users and 2 guests