VEX Precision Issues

Recommended Posts

I'm in desperate need of help here. The problem is simple, Houdini is giving some wildly inaccurate results with simple math problems. I first ran into this when using the modulo operator, but now I'm noticing it with stuff as basic as addition and subtraction. There are two things I've observed with this issue. Firstly, the problem when the numbers are variables.Secondly, the issues appears completely random. I can't find any patterns or anything.

One example is the equation: (vspacing*vpt)+voffset) - vpos.

(vspacing*vpt)+voffset) gives the correct result. vpos, is correct. But when I subtract vpos from (vspacing*vpt)+voffset) the result is simply not as it should be. For example, when the answer should be 0, the result is actually 7.45058e-9.

This is really screwing me up. I've trying trying to write some simple tools in VEX but this problem is making half the stuff I want to do absolutely impossible. Can anyone help? Does anyone know why this is happening?

Edited by DeeLan
Share on other sites

It is fundamental for float type, you can't do much there. Use nearly equal comparisons or rounding if you want to avoid precision issues in VEX, which uses 32 bit floats.

While it may be huge computer science problem, for Houdini artist it is moderately painful, all you need is to be more considerate. Comparisons will usually work if the numbers were freshly assigned, not computed by imprecise arithmetic. Therefore people usually use == and succeed most of the time.

Suppose you have points that are go down over time and you want to check if they passed ground:

```if (@P.y <= 0.0)
...
else // y > 0
...```

Don't use this:

```// Equal case (y == 0) handled in "non reached zero" branch.
if (@P.y < 0.0)
...
else // y == 0 or y > 0
...

// y == 0 never handled.
if (@P.y < 0.0)
...
else if (@P.y > 0.0)
...```

You should include equality case in one of conditions: "<= or >", "< or >=", etc., depending on the logic. This allows to handle all numbers.

If your points fall on ground and stop, you may get into troubles doing code above (consider case where point is slightly greater than zero). Instead, use some small "tolerance":

```if (@P.y <= 0.001)
...
else
...```

Actual value should be large enough to not yield visually incorrect results and encompass precision error for that scale. You can't have millimeter detail accuracy for skyscraper-sized object using 32-bit floats, and you will use value like 0.1. Coin-sized object, however, would allow you to use 0.00001 without facing precision issues.

You may find Fuse SOP in grid snapping mode with "tolerance-sized" division scale useful. It will round values to the nearest division, which fit all those "1.23456e-7" values to solid zeros.

Edited by f1480187
some tips
Share on other sites

Thanks for that! Never realized this was such an issue (or really an issue at all).

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

×   Pasted as rich text.   Paste as plain text instead

Only 75 emoji are allowed.

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×