DELPHI AREA
MESSAGE BOARD
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Possible SimpleGraph bug (well ExtGraph project bug)

 
   Reply to topic    DELPHI AREA Forum Index -> DELPHI AREA's Products
View previous topic :: View next topic  
Author Message
Specto
Member


Joined: 27 Mar 2005
Posts: 2

PostPosted: 27/03/05 21:08    Post subject: Possible SimpleGraph bug (well ExtGraph project bug) Reply with quote

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:
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:
 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:
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:
  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?



SimGTest.zip
 Description:
Example program

Download
 Filename:  SimGTest.zip
 Filesize:  231.06 KB
 Downloaded:  5 Time(s)

Back to top
View user's profile
Stefan
Junior Member


Joined: 27 Sep 2004
Posts: 73
Location: Netherlands

PostPosted: 29/03/05 13:06    Post subject: Reply with quote

Hi,

Quote:
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 Smile

Cheers,
Stefan
Back to top
View user's profile Send e-mail
Specto
Member


Joined: 27 Mar 2005
Posts: 2

PostPosted: 01/04/05 19:57    Post subject: Reply with quote

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.
Back to top
View user's profile
Display posts from previous:   
   Reply to topic    DELPHI AREA Forum Index -> DELPHI AREA's Products All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Powered by phpBB 2.0.6 © 2001, 2002 phpBB Group