I noticed that when testing a value for equality with 0, the resulting bool pattern only takes into account the very first value in a branch. Attached the image showing the issue. (‘True’ is only assigned to item #1 and not to #9 and #18) Later branches are affected as well in the same way.
Possible little bug?
Probably not. You’re working with float values, which aren’t necessarily as precise as you’d want them to. So instead of using equals you’d check if the absolute difference of the two is below some threshold value (epsilon).
For more info on floating point comparisons see for instance https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/
Thanks, I’ll give it a go
Also see this entry in the Grasshopper FAQ.
On a related note, there is the function similar, which could help in such a case, but in most of the cases you just want to test against an absolute tolerance, rather than a percentual difference.
E.g. in this use case you might want to test against 0.01, and not 0.0001% (which might still lead to a difference of 2 in large numbers). I often find myself doing a custom C# thing, or the native way would be to subtract, absolute and then a smaller/larger than.
Gee, David, I’m surprised that after all this time you haven’t made a function labelled “Equal within tolerance” or “Float Equality” - which would take a tolerance input. Or maybe a function labelled “Equal within xxxx” where xxxx would be the currently set tolerance.
So there’s three ways to compare floats that all make sense in different scenarios.
There’s the ‘within-absolute-tolerance’ approach which works fairly well within Rhino because you’re typically modelling to within a certain physical tolerance. However when you start scaling things up this can result in really nasty problems. In Grasshopper a lot of operations are more mathematical in nature than geometric, and it can be quite tricky to determine what sort of tolerance would be correct for those.
Then there’s the ‘within-relative-tolerance’ approach personified by the Similarity component. This is scale-invariant, but quite awkward to use and probably equally difficult in terms of choosing the correct threshold.
Finally there’s a more exact approach which is to measure the discrete separation between two floats, i.e. how many unique floats there are in between. This is fairly similar to relative tolerance but much faster to compute, albeit even more arcane.
It is possible that a genuinely useful comparison involves a conjunction or disjunction of both relative and absolute errors. In any case coming up with a good equality metric for a specific case is difficult and requires intimate knowledge of float accuracy. An absolute threshold input for the Equals component will be of some help, but it will not be the ultimate solution to this problem.