Evaluate my float comparison strategy, plz

Started by
35 comments, last by Nice Coder 19 years, 3 months ago
Quote:Original post by Anonymous Poster
While basananas approach might work, I don't see why you would want to complicate things like that. Just try something like

return fabs(a - b) <= epsilon * max(fabs(a), fabs(b))

or

return fabs(a - b) <= epsilon * (fabs(a) + fabs(b))


It's kind of amazing how most of code posted in this thread fail to work with negative numbers.
Advertisement
Quote:Original post by Dmytry
It's kind of amazing how most of code posted in this thread fail to work with negative numbers.

What do you mean? Why wouldn't it work with negative numbers?
Easy way to test equality
(its been a while since i've been coding in c++, so bear with me)
int32 *a;int32 *b*a = &floata*b = &gloatbif !(a ^ b) {    // Floats are equal, exactly} else {    // Floats are not equal} 


Easy way.

hard way

int32 *aint32 *bbool sabool sbint32 fracaint32 fracbint32 mantaint32 mantb*a = &floata*b = &floatbSa = a & b10000... you get the piectureSb = b & b100000 same hereFraca = a & b011111111fracb = b & b011111111Manta = a & b0000000001111111111111111111111Mantb = b & b0000000001111111111111111111111


This seperates the sign bits, fractions and mantissas from the floats.

You first check wiether the sign bits are the same, if there not then they arn't equal (i know this is a generalisation, but for most numbers that you'll be using, it'll hold true).

You can then use the mantissa to do the first equality test, ie, they should be resimably similar. just suptract them, & out the sign bit, and check if its < 2 or 3.

you then find out the difference between the two fractions, (just subract them, & out the sign bit, and see if there close enough).

And if it takes all that, then actually calculate both as integers.

You then get both ints, take the difference between them (& out the sign bit again), and divide that by the sum of the floats.

You then check weither this error is small enough to be ok.

Quote:Original post by Dmytry
Branching is costly, so handling such cases specially is not really much faster.


Actually brancing is quite fast nowdays. maybe on an 8080 it may have been very costly, but now, its really cheap. (read up on branch prediction)


HTH
From,
Nice coder
Click here to patch the mozilla IDN exploit, or click Here then type in Network.enableidn and set its value to false. Restart the browser for the patches to work.
DmyTry:
Lol, good comment about the negatives :)
I corrected my code, it should work with negatives now.

You can cut/paste from the original post, if you wanna try. Sorry for the inconvenience :)

Nice Coder:
if !(a ^ b) {...

What does "^" mean?
Quote:CalvinI am only polite because I don't know enough foul languageQuote:Original post by superpigI think the reason your rating has dropped so much, Mercenarey, is that you come across as an arrogant asshole.
Quote:Original post by Nice Coder
Quote:Original post by Dmytry
Branching is costly, so handling such cases specially is not really much faster.


Actually brancing is quite fast nowdays. maybe on an 8080 it may have been very costly, but now, its really cheap. (read up on branch prediction)

Actually, on 8080 branching costed much less than on P4 if you count cost in additions (that is, how many additions spend same time. Also, on P4 branching is more costly than on P3, etc. Read about pipelines. "branching prediction" doesn't always work, it often works with 50/50 chances.
AP: first code that uses "max" will not work. Second will work. In this thread, probability to get working code = 50/50 [grin]

Quote:Original post by Mercenarey
DmyTry:
Lol, good comment about the negatives :)
I corrected my code, it should work with negatives now.

You can cut/paste from the original post, if you wanna try. Sorry for the inconvenience :)

I don't cut-n-paste, i just see mistakes.

FloatCmp(-0.000000001,0.0000000001);

You misundestood me. "but i suggest you not to use such things." does not mean you need to write your own "universal comparison routine" that fail. You just need to drop that idea about universal float comparison routine. I doubt you have good reasons to do that comparison. If you still do not want to drop, better use my code (with apporiate abs_tolerance and rel_tolerance), it is really much faster, clealer, safer, etc. (ote that you should avoid division as it is slow.)

Your code still sucks, sorry.

Note that with negatives, if you call FloatCmp(-1,-100);
after sorting, -1 is the largest,
if(fabs(a_value2) > fabs(a_value1)*10.0f)return false;
just serves no purprose.
Note that
FloatCmp(-0.00000001,0); is true but
FloatCmp( 0.00000001,0);
and
FloatCmp(-0.00000001,-0.0000000001);
is false.

edit: sorry, i'm bit mistaken myself by double-wrongness, so first isn't true.

So, good luck with it....

[Edited by - Dmytry on January 2, 2005 3:34:25 AM]
Quote:Original post by Mercenarey
DmyTry:
Lol, good comment about the negatives :)
I corrected my code, it should work with negatives now.

You can cut/paste from the original post, if you wanna try. Sorry for the inconvenience :)

Nice Coder:
if !(a ^ b) {...

What does "^" mean?


Exclusive or

I do !(a ^ b) {

Once i've casted the floats to integers, becasue
for any binary number n ^ n = 0.
So, if both numbers are binarily equal (all the bits are equal), then when there xored together, they evaluate to 0.

I then add the !, so that the 0 from the xor, (which is taken as false), gets negitated to 1, (which is TRUE (actual names, defined soemwhere)).

Just doing my job. I'm not called Nice coder for nothing you know...

From,
Nice coder
Click here to patch the mozilla IDN exploit, or click Here then type in Network.enableidn and set its value to false. Restart the browser for the patches to work.
Quote:Original post by Dmytry
Quote:Original post by Nice Coder
Quote:Original post by Dmytry
Branching is costly, so handling such cases specially is not really much faster.


Actually brancing is quite fast nowdays. maybe on an 8080 it may have been very costly, but now, its really cheap. (read up on branch prediction)

Actually, on 8080 branching costed much less than on P4 if you count cost in additions (that is, how many additions spend same time. Also, on P4 branching is more costly than on P3, etc. Read about pipelines. "branching prediction" doesn't always work, it often works with 50/50 chances.


I've already read about branch prediction, and its quite good.

Although the pipeline gets in the way (a lot), conditional jumps are pretty fast. It just depends on how you use them.

From,
Nice coder
Click here to patch the mozilla IDN exploit, or click Here then type in Network.enableidn and set its value to false. Restart the browser for the patches to work.
Quote:Original post by Dmytry
AP: first code that uses "max" will not work. Second will work. In this thread, probability to get working code = 50/50 [grin]

Still can't see why it wouldn't work. Can you explain?
Quote:Original post by Anonymous Poster
Quote:Original post by Dmytry
AP: first code that uses "max" will not work. Second will work. In this thread, probability to get working code = 50/50 [grin]

Still can't see why it wouldn't work. Can you explain?

ops, sorry man, somehow haven't noticed fabs(a) and fabs(b) in max.(and would bet 'em wasn't there[grin] ) Will remember not to post into math & physics at first day of new year... :(

This topic is closed to new replies.

Advertisement