1== 1 is False?

Bengt Richter bokr at oz.net
Fri Jun 20 17:11:17 EDT 2003


On Fri, 20 Jun 2003 16:07:34 +0200, delphiro <delphiro at zonnet.nl> wrote:

>Hi,
>
>I get a strange error stating that two equal values are not equal. In short what I do;
>
>I calculate the intersection point of two linesegments. If they intersect I check if the intersections point is within both linesegmenents. The code for the latter is;
>
>[CODE]
>def GetLineSegmentIntersection( p1, p2, p3, p4 ): 
>	p = GetLineIntersection( p1, p2, p3, p4 )
Presumably p may have some roundoff error in its coordinates, even if e.g., p1==p3, unless
some of these cases are special cased.
>	#do we have an intersection at all?
>	if p == []:
>		return []
>	xmax = _MAX( p1[0], p2[0] )
>    	ymax = _MAX( p1[1], p2[1] )
>	xmin = _MIN( p1[0], p2[0] )
>	ymin = _MIN( p1[1], p2[1] )
>   	#within range of line 1?
>    	if( p[0] <= xmax )and( p[0] >= xmin)and( p[1] <= ymax )and( p[1] >= ymin ):
>        	#line 2
>        	xmax = _MAX( p3[0], p4[0] )
>        	ymax = _MAX( p3[1], p4[1] )
>        	xmin = _MIN( p3[0], p4[0] )
>        	ymin = _MIN( p3[1], p4[1] )
>		if( p[0] <= xmax )and( p[0] >= xmin)and( p[1] <= ymax )and( p[1] >= ymin ):
>       	     		return array((p[0],p[1]))
>	#if we get here then the point is not within the linesegments
>	return []
>[/CODE]
>
>This works fine but for some strange reason I sometimes the statement for the check of line 2 is NOT valid if p[1] == ymax == ymin. 
>
>If I print out the values I get something like 2.260212 <= 2.260212 and 2.260212 >= 2.260212 is NOT true.
>
>What's wrong?
Probably roundoff. If you have the source for GetLineIntersection, you might fix this kind
of special case -- if it's worth it -- by checking if either endpoint coincides with an
endpoint of the other line) and returning the coinciding p1 or p2 without computing the usual way.

To see the difference between two doubles, print the difference (i.e., f1-f2) ;-)
repr(f1) vs repr(f2) should also show a difference if they're different. You are probably
looking at the str(f) representation, which is designed to present numbers without long tails of 9's etc.

Depending on what you are doing with your computations, you might want to compute using
units that correspond to some practical problem resolution (e.g. pixels) while
maintaining fractional units in the floating calculations. You may then find it interesting
to compare visual effects of passing int(x),int(y) vs floor(x),floor(y), vs round(x),round(y)
as coordinates to the graphics functions.

A test that often shows anomalies quickly is to do the same geometric problem in various orientations
and mirrorings. If you are plotting results, the eye will often pick out little differences between
e.g. left and right mirror images. You may even discover a bug in your algorithms such as folklore
says made a fighter plane on autopilot flip roll to upside down when it crossed the equator ;-)

Graphics anomalies may lead you to investigate what the graphics library you are using thinks the
definition of pixel and coordinate is, to get those last one-pixel differences out ;-)

If you plot two line 'stars' (angularly evenly spaced lines radiating from the same point)
and offset their centers slightly, you will get moire effects that reveal a lot about the plotting,
and will show differences for int, floor, and round.

BTW, if you need to test radial distance someplace, don't bother with the square root, compare the
sum of the squares against distance squared instead.

Regards,
Bengt Richter




More information about the Python-list mailing list