Bug?!?! Floating point error python

   8786   12   2
User Avatar
Member
665 posts
Joined: July 2005
Offline
This one is killing me.

I've set a geo node to have a ‘tx’ parameter equal to ‘0.15’
Then query that parameter w/ python

>>> test = hou.node('/obj/geo1')
>>> print test.parm(“tx”).eval()
0.15000000596


Where as a hscript query gives me

-> echo `ch('/obj/geo1/tx')`
0.15


This is getting a bit frustrating, am I doing something wrong here?

cheers,
-j
User Avatar
Member
4140 posts
Joined: July 2005
Offline
It's not you, but I'd hesitate to call it a bug. Basically Python is wired to return the full value, while hscript has always truncated the double floats. Internally(whats really there), it's closer to the Python value.

Note that should this actually become an issue(usually it isn't since you're typically not mixing hscript and HOM in the same process), there are some nicieties in there like hou.almostEqual(x,y) which would return True in your example.

Cheers,

J.C.

P.S. Sorry, I missed a key point - you want to know why 0.15 entered into a field gets ‘changed’. That's what happens when you get into the wonderful world of double floats. It's just a byproduct of the hardware. I'm lazy this morning so I stole this short description of why from a java(gulp) article :

What actually happens is the computer only has 64 bits to work with. It has to throw away the low order part of any result after every operation. On every calculation you accumulate a little more roundoff error.
John Coldrick
User Avatar
Member
665 posts
Joined: July 2005
Offline
Wow, I'm not even sure where to start

1) My innocent world of entering values in to Houdini seems to have been crushed.
Why, for the love of god, did I not enter ‘0.15’ in the field? I typed it, why isn't it still there? It's not like I'm dividing or anything?

2) Why do Hscript and Python query different numbers?

3) Because I gather this shows me off as one still not comfortable with the deep and scary world of floating points underbelly. Is there any way for me to return exactly what the fluffly land of hscript returns?
I don't imagine a almost equal function will make me very comfortable in many cases.


cheers,
-j
User Avatar
Member
4140 posts
Joined: July 2005
Offline
1. It happens all over the place, not just Houdini. I suspect the reason its there in Python, however, is that simply by using Python and HOM you're doing some sort of operation.
2. As I mentioned, they *aren't* referencing different things. hscript has always kept things a little ‘simpler’ when displaying values that might have a .0000001 buried in there. Python is python. SESI can't tell Python how to do it's job. They're referencing the same thing, just the display is different.
3. Give me an example(simple one, of course) where this is a real problem for you. It's always been there, just hidden from view. We are talking about extremely small numbers here. If you're concerned about needing to do a conditional for an if: statement, that function call I quoted could handle that for you. Most of the time you need to know that two things are *precisely* the same, they're integers, but that call can even cover the other scenario.

This really isn't something that should cause any grief!

Cheers,

J.C.
John Coldrick
User Avatar
Member
12469 posts
Joined: July 2005
Offline
This really isn't something that should cause any grief!

I agree - it's odd and intially confusing I agree, but the few times I've experienced it myself it has not actually affected my work at all; not to say that it won't affect you

This is one of the reasons why it's standard practise to have some tolerance value when doing floating-point comparisons (the ‘epsilon’ value).

See Marios page here: http://odforce.net/wiki/index.php/Equal [odforce.net]

Cheers,
Jason
Jason Iversen, Technology Supervisor & FX Pipeline/R+D Lead @ Weta FX
also, http://www.odforce.net [www.odforce.net]
User Avatar
Staff
1072 posts
Joined: July 2005
Offline
What is happening here is that 0.15 cannot be exactly represented as a floating point number (single or double precision), which is how Houdini stores it (single precision).

Python probably promotes this single precision value to double precision, but this doesn't add any extra precision. What was the best single precision approximation is not the best double precision approximation. Had this number started life as a double precision approximation, then it would be much closer of an approximation to 0.15 than we have here, and would likely display as 0.15. Or not, as you'll see if you follow the link I'll mention below.

See http://docs.python.org/tut/node16.html [docs.python.org] for more information.
User Avatar
Member
7722 posts
Joined: July 2005
Online
Ondrej
What is happening here is that 0.15 cannot be exactly represented as a floating point number (single or double precision), which is how Houdini stores it (single precision).

To save you from reading the link, the reason why 0.15 can't be represented exactly as a floating point number is because it uses a base of 2, not base of 10. If IEEE floating point numbers used base 10, then this wouldn't have been a problem. The old mainframes used a base 10 representation but I think that is disappearing. See: http://en.wikipedia.org/wiki/Binary-coded_decimal [en.wikipedia.org]
User Avatar
Member
2199 posts
Joined: July 2005
Online
I ran into this for a different reason and ended up doing this


def decimal(num):
floatValue = float(num)
fixedFloat = “%.4f” % floatValue
return float(fixedFloat)


This truncates the values returned to 4 decimal places which was all I needed at the time. Maybe its useful to you.
The trick is finding just the right hammer for every screw
User Avatar
Member
63 posts
Joined: July 2005
Offline
Why not use the dedicated Decimal module in Python ti do this kind of stuff?
User Avatar
Member
4140 posts
Joined: July 2005
Offline
All sorts of ways to deal with this thing that also scared the hell out of me the first time I found out about it. Uprooted my sense of what was going on behind the screen, similar to the way you felt when you first really *got* the basic concepts behind the general theory of relativity. I love computers.

Cheers,

J.C.
John Coldrick
User Avatar
Member
2199 posts
Joined: July 2005
Online
diula
Why not use the dedicated Decimal module in Python ti do this kind of stuff?

Cos I didn't know about it, and this was what I found on google after a quick search. 8)
The trick is finding just the right hammer for every screw
User Avatar
Member
665 posts
Joined: July 2005
Offline
Hi guys,

Thanks for all the replies, I think my brain is slowly expanding to allow for this new world of double floats. Let me tell you it was painful

Ondrej was kind enough to pass along the test.parm(“tx”).evalAsString() function which will return the string representing what Houdini stores.

cheers,
-j
User Avatar
Member
55 posts
Joined: Jan. 2006
Offline
1/10,000,000 (or so)

Is it really that big of a deal? It's only one inch in 157 miles, 4337 feet, 4 inches, 276 microns, 352 nanometers.

That's like loosing 1 out of 6 marathons by an inch while tying the other 5 exactly.



I hope that was humorus.
“If you can eat it raw you can't under cook it”
  • Quick Links