As Nathan pointed out, the difference you're seeing is indeed a single
precision floating point issue.

Basically, 1054.123456 cannot be exactly represented as a single precision
float.
The closest single float value is 1054.1234130859375, which is what you're
getting (except that a truncated version is being printed out)

An easy way to check is to use the c_float type from ctypes, which is
single precision, vs the double precision float type  in python.

  import ctypes

print ctypes.c_float(1054.123456)

Also, if it helps, your hex2float function can probably be simplified using
the string.decode() method:

  def hex2float(s):

import struct

return struct.unpack( '!f', s.lstrip('x').decode('hex'))[0]

Hope that helps.

Cheers,
Ivan





On Wed, May 8, 2013 at 2:23 PM, Nathan Rusch <nathan_ru...@hotmail.com>wrote:

> Have you tried confirming that the value you enter in a knob is even
> stored as-is to begin with? I think that's the piece you're missing. For
> example, I created a Roto, added a shape, and set its 'center.x' value to
> your input float (1054.123456). Upon closing reopening the control panel,
> the knob displays the exact value you're seeing: 1054.12341309.
>
> In other words, what you're seeing appears to be standard floating-point
> precision loss, occurring when the text entered by the user is converted
> and stored. I would guess that the closing and reopening is what causes
> Nuke to pull that value back out of the knob's storage memory to display in
> the bin.
>
> Also, 43b40000 should translate to 360.0. Your value (or the
> floating-point approximation of it) is stored as 4483c3f3.
>
> Hope this helps.
>
> -Nathan
>
>
> -----Original Message----- From: Magno Borgo
> Sent: Wednesday, May 08, 2013 11:09 AM
> To: 
> nuke-python@support.**thefoundry.co.uk<nuke-python@support.thefoundry.co.uk>
> Subject: [Nuke-python] Parsing hex float values - precision loss
>
>
> Hello.
>
> I working on a script parser that takes the raw .nk file and do some magic.
> The v7 roto format stores the animated float values using hexadecimal
> literals
> (http://docs.thefoundry.co.uk/**nuke/70/ndkdevguide/advanced/**
> rotoformat.html<http://docs.thefoundry.co.uk/nuke/70/ndkdevguide/advanced/rotoformat.html>
> ),
> something like this:
>
> x41200000 (this is 10)
> x43b40000 (this is 1054.123456)
>
> after some research on the interwebs  I managed to found a way to convert
> these back to float using this function:
>
> def hex2float(s):
>       #s is a string like x4000000, we need only the 4000000 part:
>       s = str(s.group().lstrip()[1:])
>       bins = ''.join(chr(int(s[x:x+2], 16)) for x in range(0, len(s), 2))
>       return str(struct.unpack('>f', bins)[0])
>
> But I'm running into some precision loss after the conversion, for example
> x43b40000 is originally 1054.123456, after conversion using the function
> above 1054.12341309
>
> Any tips on this kind of conversions?
>
> Thanks in advance,
> --
> Magno Borgo
> www.boundaryvfx.com
> www.borgo.tv
> Brasil:Curitiba:GMT= -3
> ______________________________**_________________
> Nuke-python mailing list
> Nuke-python@support.**thefoundry.co.uk<Nuke-python@support.thefoundry.co.uk>,
> http://forums.thefoundry.co.**uk/ <http://forums.thefoundry.co.uk/>
> http://support.thefoundry.co.**uk/cgi-bin/mailman/listinfo/**nuke-python<http://support.thefoundry.co.uk/cgi-bin/mailman/listinfo/nuke-python>
> ______________________________**_________________
> Nuke-python mailing list
> Nuke-python@support.**thefoundry.co.uk<Nuke-python@support.thefoundry.co.uk>,
> http://forums.thefoundry.co.**uk/ <http://forums.thefoundry.co.uk/>
> http://support.thefoundry.co.**uk/cgi-bin/mailman/listinfo/**nuke-python<http://support.thefoundry.co.uk/cgi-bin/mailman/listinfo/nuke-python>
>
_______________________________________________
Nuke-python mailing list
Nuke-python@support.thefoundry.co.uk, http://forums.thefoundry.co.uk/
http://support.thefoundry.co.uk/cgi-bin/mailman/listinfo/nuke-python

Reply via email to