0 ≠ 0 ...can someone explain?

I run into something today that really confuses me

apparently, not all zeros are the same

not all zeros are the same.gh (7.9 KB)

@guido
For some reason, the other ‘0’ is just a very small floating point.
If I recall correctly, the numbers are shown in components, with 6 decimal rounded values…

2 Likes

Welcome to the world of computers and floating point numbers. When working with floating point numbers you should not rely on equality, especially not bit-for-bit.

There are quite many posts about it on our discourse, but my all-time favourite is

and the reaction to it

See

for links to more information.

In the end, when working with floating point numbers you’ll have to literally take it all with a grain of salt (called epsilon).

3 Likes

@guido
These two first method seem to work.
I use often the ‘Similarity’ component, but here even at 90% it fails. Which it shouldn’t.


@nathanletwory Can you explain the Similarity component not working here?

Interesting. I also noticed that both convert to a false boolean.

compare_floats.gh (10.5 KB)

use an Expression is the most readable version I think.
integrate epsilon into the expresion or as an alternative Parameter

not sure about performance.
@Toni
but i am quite sure, that first convert to String and then compare the Strings is not the most elegant way, and not very performative (but a maybe a simple workaround for some other approaches)

@Toni_Osterlund
As fare as i understood Similarity uses Percantage from 0.0…1.0 not from 0…100

kind regards -tom

1 Like

In my experience, you can skip the ‘epsilon equals’ check if the floating numbers provided are never the result of a calculation, but of an assignment instead. In one of my projects I do exchange data from another application and I thread any scalar number from that other system as a double for interface simplicity. I know that in that system it might be a short integer (e.g. used as an enumeration in that system), but I can still directly apply a direct check, since that number is 0.0. And not something slightly above or below. That use-case is a rare one, so in general you simply don’t know if the number is calculated or not.

Performance considerations should only be made if there is a problem. But the expression component is not known for being very performant.

1 Like

@Tom_P You’re right that the string compare is nor elegant or fast.

With the ‘Similarity’, can you explain this? @nathanletwory
@Tom_P I’ve used it with the assumption of 0-100%. But with these very small numbers close to 0, the results are not coherent.

…I think I got it now - you cannot compare percentages with 0 value [something like (A-B)/B = %]. So Similarity does not work on comparing 0-values…

Similarity.gh (11.7 KB)

Just leaving this gold nugget here

https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html

4 Likes

(as fare is i understood) similarity is doing a percentage (relative) compare.
0.001 is 100 times bigger then 0.00001
for those small numbers you should do an absolute compare using a epsilon (threshold) as @nathanletwory pointed out.

using panels means using text/strings that might be (or might not be) converted to numbers at some point of the inner logic of the component or depending on the grasshopper preferences, or … - be careful.

1 Like

Ok, so we determined that we have a very small floating-point that appears to be zero.

Now …how is this possible?

some zeros are smaller than others.gh (11.8 KB)

I guess as they’ve tried to explain…floating-point math is wacky. The numbers you think you’re working with aren’t actually what are being worked with, they’re converted to base 2, and there are rounding errors everywhere and the errors aren’t even consistent some numbers just don’t translate very well. And going from your input to your output they’re passing through 20 layers of crap that all may adulterate them in their own way.

1 Like

You have answered your own question

When you look at values with full precision, you can see that the value at index 10 is -2.7755575615628914E-16 which is indeed less than zero.

Edit: Removed incorrect information.

some zeros are smaller than others_re.gh (8.9 KB)

-Kevin

1 Like

How does the explanation of @kev.r differ to @Toni_Osterlund and @nathanletwory?

The correct solution is not to use “round” or “delta percentage” calculation, but the “epsilon equal” check shown by @Tom_P and mentioned by @nathanletwory.

3 Likes

For those of you who are doing this in code, see the EpsilonEquals method

https://developer.rhino3d.com/api/RhinoCommon/html/Overload_Rhino_RhinoMath_EpsilonEquals.htm

2 Likes

Apologies for supplying incorrect information, I’ve edited my post above to remove the suggestion to use rounding as a solution for this.

-Kevin

1 Like

Sorry …also happens to me. I put the effort in answering a question but the dude asking just doesn’t get it. Give me a bit of time, it’s not easiest topic.