openscad / openscad

OpenSCAD - The Programmers Solid 3D CAD Modeller
https://www.openscad.org
Other
6.83k stars 1.2k forks source link

Echo shows incorrect data #107

Closed brad closed 12 years ago

brad commented 12 years ago

length = 75.6; echo(length);

produces:

ECHO: 75.59999999999999

donbright commented 12 years ago

i think 75.6 might not be representable exactly in binary except as a series of infinite binary fractions, so the same problem occurs with any computer language that internally stores floating point numbers using a real actual physical CPU floating point type with a limited number of bits (32, 64, whatever) (ie. in python type 'x=75.6' then 'float(x)'.)

more info:

http://stackoverflow.com/questions/1089018/why-cant-decimal-numbers-be-represented-exactly-in-binary

http://www.learncpp.com/cpp-tutorial/25-floating-point-numbers/

to solve this, you could theoretically hack Value.h/Value.cpp to use GNU GMP (stores numbers as fractions) instead of 'double', but i dont know how much that might slow down openscad's OpenCSG mode??? most languages seem to get along OK without doing this , they just round output or something (like in C++, cout << precision by default gives 75.6, but if you cout << setprecision(16) , you will get 75.5999etcetcetc )

curiouser and curiouser....

---- update

here is a very cool page - Lisp has rationals built in to the language.... anyways...

http://en.wikipedia.org/wiki/Rational_data_type

brad commented 12 years ago

Hmm, point taken, I have been programming a long time and don't remember ever encountering this issue. It's not a problem with Python either. I suppose this is not likely to get fixed since it is a bug in C++

donbright commented 12 years ago

python example

don@age:~$ python
xPython 2.6.5 (r265:79063, Apr 16 2010, 13:09:56) 
[GCC 4.4.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> x=75.6
>>> float(x)
75.599999999999994
>>> 

simpler python example

don@age:~$ python
Python 2.6.5 (r265:79063, Apr 16 2010, 13:09:56) 
[GCC 4.4.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> x=75.6
>>> x
75.599999999999994
>>> print x
75.6
>>> 
brad commented 12 years ago

I guess it must be fixed in 2.7 Python 2.7.2+ (default, Oct 4 2011, 20:06:09) [GCC 4.6.1] on linux2 Type "help", "copyright", "credits" or "license" for more information.

x = 75.6 type(x) <type 'float'> print x 75.6 x 75.6

donbright commented 12 years ago
don@age:~$ python3.1 
Python 3.1.2 (r312:79147, Dec  9 2011, 20:54:36) 
[GCC 4.4.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> x=75.6
>>> x
75.6
>>> '%.17f' % x
'75.59999999999999432'
>>> 

(see http://mail.python.org/pipermail/tutor/2007-December/058964.html )

i.e. python is not storing the rational number 75.6 its storing the binary number 75.599999..... (the infinite series truncated based on how many bits the machine has)

if it is just a question of you want ECHO to be 'rounded', there is probably somewhere in the source code that it could easily be changed.... ???

brad commented 12 years ago

OK, you got me. I guess it is an issue with Python. I guess the newer versions simply hide it better by rounding to the same number of decimal places that you input the number with.

Anyway, I really don't think this is an issue.