Problem with floating point numbers.

S

sajin

Guest
Hi all
I was trying to find the size of a paticular shape. When i
take bBox and use some comparisons, the script was giving false errors
evenif the calculated value was correct. I think the problem is coming
from the floating point value of the bBox which i dont know how is it
stored. Is there any work around for this.

Thanking all in advance
Sajin
 
sajin wrote:
Hi all
I was trying to find the size of a paticular shape. When i
take bBox and use some comparisons, the script was giving false errors
evenif the calculated value was correct. I think the problem is coming
from the floating point value of the bBox which i dont know how is it
stored. Is there any work around for this.
If you post the code of your comparison it would be easier to comment,
because If you don't know how the bBox is stored, it would be difficult
to extract the coordinates of the bBox properly.

--
Svenn
 
Hi Svenn

The code is looking like this,

b=setof(x cv~>shapes (x~>lpp=='("m6" "pin")|| x~>lpp=='("m5" "pin")||
x~>lpp=='("m4" "pin") || x~>lpp=='("m3" "pin"))
foreach(c b
d=c~>bBox
f1=truncate(caar(d)*1000.0)
f=f1/1000.0
g1=truncate(caadr(d)*1000.0)
g=g1/1000.0
h1=truncate(cadar(d)*1000.0)
h=h1/1000.0
i1=truncate(cadadr(d)*1000.0)
i=i1/1000.0
if((abs(f-g)!=4.5 || abs(h-i)!=4.5) then
printf("%L in %L %L %L %L is
wrong\n",c~>net~>name,c~>lpp,abs(f-g),abs(h-i),d)
)

So the problem i am facing is that evenif the size is 4.5 it will get
printed as wrong.
the above code i have done using truncation because i was trying to
avoid the problem with the floating point.

Thanking you in advance
Sajin
 
In article <1156507585.639621.138810@i3g2000cwc.googlegroups.com> "sajin" <sajinvm@gmail.com> writes:
Hi Svenn

The code is looking like this,

b=setof(x cv~>shapes (x~>lpp=='("m6" "pin")|| x~>lpp=='("m5" "pin")||
x~>lpp=='("m4" "pin") || x~>lpp=='("m3" "pin"))
foreach(c b
d=c~>bBox
f1=truncate(caar(d)*1000.0)
f=f1/1000.0
g1=truncate(caadr(d)*1000.0)
g=g1/1000.0
h1=truncate(cadar(d)*1000.0)
h=h1/1000.0
i1=truncate(cadadr(d)*1000.0)
i=i1/1000.0
if((abs(f-g)!=4.5 || abs(h-i)!=4.5) then
printf("%L in %L %L %L %L is
wrong\n",c~>net~>name,c~>lpp,abs(f-g),abs(h-i),d)
)

So the problem i am facing is that evenif the size is 4.5 it will get
printed as wrong.
the above code i have done using truncation because i was trying to
avoid the problem with the floating point.
Your problem is that you have to understand that floating point numbers are
not precise. You have to do "fuzzy compares" within a tolerance in order to
get accurate results with floating point numbers.

That has nothing to do with Skill, but has to do with how floating point
numbers are represented within computers.

4.5 could actually be 4.5000000000012974 or 4.4999999999994218 (for example).

So you have to calculate a tolerance.

For example, use:

procedure(MyFloatCompare(testNum comparator tolerance)
testNum <= comparator + tolerance && testNum >= comparator - tolerance
)

MyTolerance = 0.0000001

if((!MyFloatCompare(abs(f-g) 4.5 MyTolerance) ||
!MyFloatCompare(abs(h-i) 4.5 MyTolerance)) then ...

Form more info regarding floating point numbers, refer to David Goldberg's
paper on the subject: "What Every Computer Scientist Should Know About
Floating-Point Arithmetic." It can be found at:

http://docs.sun.com/source/806-3568/ncg_goldberg.html

-Pete Zakel
(phz@seeheader.nospam)

"When more and more people are thrown out of work, unemployment results."

-Calvin Coolidge
 
In your example you are reading two numbers from the data base,
doing some calculation with them and then dividing by 1000.0. This
division
produces round off error because .001 is a repeating decimal number
in binary and thus not expressed exactly. Next you subtract the two
numbers which decreases your percision even more. Next
you are comparing to 4.5 and hoping that magically all the round off
error has vanished.

The floating point problem is not unique to SKILL. You'll see the same
type of problem in many languages that support floating point
arithmetic.
Try a comparison like the following in other languages and tell me what
results .001 == (1.0 / 1000.0) * 1000.0

One good way of comparing floating point numbers in SKILL is to compare
their printed representations because that is most often what you
really
want to do. try a function like the following

(defun float_equal (a b)
(or (equal a b)
(equal (sprintf nil "%L" a) (sprintf nil "%L" b))))

This will return t either if they really are equal or if their printed
representations are the same.

good luck.
-jim



sajin wrote:
Hi Svenn

The code is looking like this,

b=setof(x cv~>shapes (x~>lpp=='("m6" "pin")|| x~>lpp=='("m5" "pin")||
x~>lpp=='("m4" "pin") || x~>lpp=='("m3" "pin"))
foreach(c b
d=c~>bBox
f1=truncate(caar(d)*1000.0)
f=f1/1000.0
g1=truncate(caadr(d)*1000.0)
g=g1/1000.0
h1=truncate(cadar(d)*1000.0)
h=h1/1000.0
i1=truncate(cadadr(d)*1000.0)
i=i1/1000.0
if((abs(f-g)!=4.5 || abs(h-i)!=4.5) then
printf("%L in %L %L %L %L is
wrong\n",c~>net~>name,c~>lpp,abs(f-g),abs(h-i),d)
)

So the problem i am facing is that evenif the size is 4.5 it will get
printed as wrong.
the above code i have done using truncation because i was trying to
avoid the problem with the floating point.

Thanking you in advance
Sajin
 

Welcome to EDABoard.com

Sponsor

Back
Top