0
$\begingroup$

I'm looking for a way to copy exactly the value of a float into the attribute of a Blender object, but I see a loss of precision on the last 5 digits.

For example I want to copy -0.18958371707600324 in bpy.data.movieclips['untitled.png'].tracking.camera.brown_k1 and when I do:

bpy.data.movieclips['untitled.png'].tracking.camera.brown_k1 = -0.18958371707600324

It stores -0.18958371877670288 into bpy.data.movieclips['untitled.png'].tracking.camera.brown_k1, instead of -0.18958371707600324.

I observe the same issue with other attributes, like bpy.data.objects['Plane'].rotation_axis_angle[0].

And if I create two floats A1 and A2 so that:

A1 = -0.18958371707600324
A2 = 2.
A2 = A1 

I obtain A2 = -0.18958371707600324 so no problem here.

Any idea? The use of decimal.Decimal objects doesn't seem to solve the problem.

Thanks in advance!

$\endgroup$
3
  • $\begingroup$ Hello, that's a common float precision problem. As far as Blender is concerned those numbers are equal. Do you really need that amount of decimal places ? You're talking precision equivalent to the size of the smallest elementary components of matter known to man (10^-18 m). If you want to store a decimal number with an exact precision you can store it as a string and convert it to / from float when needed $\endgroup$
    – Gorgious
    Aug 18, 2023 at 7:53
  • $\begingroup$ Hi, so I try to simulate a specific camera with precision and I observe a small but existing shift that I associate to the loss in the various distortion parameters (brown model). I'm not sure how storing the value into a string would transfer properly the exact value to the attribute (I mean more than I did), can you please be more specific? $\endgroup$
    – GBA
    Aug 18, 2023 at 8:12
  • $\begingroup$ In other words, my problem is on transferring the value, not storing it. $\endgroup$
    – GBA
    Aug 18, 2023 at 8:34

1 Answer 1

2
$\begingroup$

You have more than 5 digits precision loss:

-0.18958371707600324
-0.18958371877670288
           ^^^^^^^^^

This is basically the half precision which makes sense because float in Python has double precision (a.k.a. double) whereas Blender objects use FloatPropertys which have single precision, quote:

Returns a new float (single precision) property definition.

You can convince yourself with a little script that it's this loss of precision:

from ctypes import *
val = -0.18958371707600324   
print("double precision", c_double(val).value) # gives -0.18958371707600324
print("single precision", c_float(val).value)  # gives -0.18958371877670288

If you're curious, you can see the properties with:

for p in bpy.data.movieclips['untitled.png'].tracking.camera.bl_rna.properties:
    print(p)

which prints

...
<bpy_struct, FloatProperty("brown_k1") at 0x00007FF65AB76700>
...

So you are out of luck storing -0.18958371707600324 in brown_k1.

$\endgroup$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .