Precision of float values in list

Hello,

I must collect coordinate points (x, y, z) and therefor used a list to store them as tuples. Although I use the round function to just get values with two decimals, the values in the list are extended to values with 14 decimals.

So I tried to find the problem and came up with:

import rhinoscriptsyntax as rs

matrix = []
x = 543.1
y = 345.33
z = 369.329
matrix.append([x, y, z])

x = 543.2
y = 345.35
z = 369.327
matrix.append([x, y, z])

x = 543.3
y = 345.37
z = 369.326
matrix.append([x, y, z])

x = 543.5
y = 345.38
z = 369.325
matrix.append([x, y, z])

x = round(543.6738448321, 2)
y = round(1345.33324332, 3)
z = round(369.84264326, 4)
matrix.append([x, y, z])

for m in matrix:
    print(m)

results in

[543.10000000000002, 345.32999999999998, 369.32900000000001]
[543.20000000000005, 345.35000000000002, 369.327]
[543.29999999999995, 345.37, 369.32600000000002]
[543.5, 345.38, 369.32499999999999]
[543.66999999999996, 1345.3330000000001, 369.8426]

Strange, isn’t it? Where is the mistake? How to solve it and get just the values defined

Regards, MillingGuy

listDecimals.py (648 Bytes)
I extended the output with different variations. still very odd, but the last one is interesting, as it shows the values of x as they were given in the source code.
Bye, MillingGuy

Hey @MillingGuy,

This might be worth your time.

https://ironpython-test.readthedocs.io/en/latest/tutorial/floatingpoint.html

– Dale

Thanks, Dale. Yep… floating and base10 or base2. All not that easy.

But I’m still wondering, why …

import rhinoscriptsyntax as rs

matrix = []
x = 543.1
y = 345.33
z = 369.329
matrix.append([x, y, z])

print(matrix[0])
print(matrix[0][0], matrix[0][1], matrix[0][2])

for m in matrix:
    print(m)
   
print(matrix[0][0])
[543.10000000000002, 345.32999999999998, 369.32900000000001]
(543.10000000000002, 345.32999999999998, 369.32900000000001)
[543.10000000000002, 345.32999999999998, 369.32900000000001]
543.1

… in list views the values are not truncated as it does when just fetching a single one.

Bye, MillingGuy

Try this:

matrix = []

x = 543.6738448321
y = 1345.33324332
z = 369.84264326
matrix.append([x, y, z])

x = round(543.6738448321, 2)
y = round(1345.33324332, 3)
z = round(369.84264326, 4)
matrix.append([x, y, z])

for m in matrix:
    print(m)
print("---")    
for m in matrix:
    print(m[0], m[1], m[2])
print("---") 
for m in matrix:
    print "{},{},{}".format(m[0],m[1],m[2])
print("---") 
for m in matrix:
    print "{:.2f},{:.3f},{:.4f}".format(m[0],m[1],m[2])
[543.67384483210003, 1345.3332433200001, 369.84264325999999]
[543.66999999999996, 1345.3330000000001, 369.8426]
---
(543.67384483210003, 1345.3332433200001, 369.84264325999999)
(543.66999999999996, 1345.3330000000001, 369.8426)
---
543.673844832,1345.33324332,369.84264326
543.67,1345.333,369.8426
---
543.67,1345.333,369.8426
543.67,1345.333,369.8426

Hi @Helvetosaur
hmm… is this for me or @dale ?
Your output is either strange, too. Why is z=369.8426 well done in second output, whereas x and y remains with more decimals as defined with the round function?

Yes… output will be done correct, if one is direct accessing the values given the system no chance to interpret it to be a list:

print("---") 
for m in matrix:
    print(m[0])
    print(m[1])
    print(m[2])
    print(str(m[0]) + ", " + str(m[1]) + ", " + str(m[2]))
---
543.673844832
1345.33324332
369.84264326
543.673844832, 1345.33324332, 369.84264326
543.67
1345.333
369.8426
543.67, 1345.333, 369.8426

Bye, MillingGuy

All floating point numbers are likely to have some ‘fuzz’. What you think is 543.67 may really be stored as 543.6700000002

When you print, python turns numbers into strings. How it does that exactly and what the rules are for truncation are is somewhat of a mystery to me - so I prefer to be certain of my output. The format method provides that certainty - as well as letting you do the truncation yourself if you want.

Hi,

Me too.

So it is good to know about it and to be “careful” when working with floats in lists.
Bye, MillingGuy