This post is about how OpenScad type-casts a floating point number to a
string(str()) or displays it in the console (echo()). I.e., nothing to do
with the internal calculation. Observation is carried out with OpenSCAD
version 2015.06.21.nightly (git 68e41af) running on Linux Mint 17.
I. First we know that round() gets rid of 4, advances 5:
round(1.4) => 1
round(1.5) => 2
round(4.4) => 4
round(4.5) => 5
round(5.4) => 5
round(5.5) => 6
II. OpenScad displays only 6 significant digits. I would expect extra
significant digits to be treated as the way round() works, i.e., cut 4,
advance 5. But it is not:
II-1. Integer -- When extra significant digit is 5, simply cut away:
str(123456) = 123456
str(1234560) = 1.23456e+06 // Sci.Notation
str(1234564) = 1.23456e+06 // 4 gets cut
str(1234565) = 1.23456e+06 // Why not 1.23457 ?
str(1234566) = 1.23457e+06 // 6 advances
II-2. Float (>=1) -- Rounded up normally to 6 significant digits: cut 4,
advance 5:
str(1.123456) = 1.12346
str(1.0123456) = 1.01235
str(1.00123456) = 1.00123
str(1.000123456) = 1.00012
str(1.0000123456) = 1.00001
II-3. Float (<1) -- 5 sometimes cut, sometimes advances:
str(0.1234565) = 0.123456 // Why is 5 cut?
str(0.01234565) = 0.0123456 // Why is 5 cut?
str(0.001234565) = 0.00123456 // Why is 5 cut?
str(0.0001234565) = 0.000123457 // 5 advances
str(0.00001234565) = 1.23456e-05 // Why is 5 cut?
III. This section is to test 6 digits + a 5, like 0.1111115, 0.2222225, etc,
and multiply them with 0.1 repeatedly. It appears that the extra-5 is
treated in an irregular manner:
str(0.1111115) = 0.111112
str(0.01111115) = 0.0111112
str(0.001111115) = 0.00111111 // Why is 5 cut?
str(0.0001111115) = 0.000111111 // Why is 5 cut?
str(0.00001111115) = 1.11111e-05 // Why is 5 cut?
str(0.2222225) = 0.222222 // Why is 5 cut?
str(0.02222225) = 0.0222222 // Why is 5 cut?
str(0.002222225) = 0.00222222 // Why is 5 cut?
str(0.0002222225) = 0.000222223
str(0.00002222225) = 2.22222e-05 // Why is 5 cut?
str(0.3333335) = 0.333334
str(0.03333335) = 0.0333333 // Why is 5 cut?
str(0.003333335) = 0.00333334
str(0.0003333335) = 0.000333334
str(0.00003333335) = 3.33333e-05 // Why is 5 cut?
str(0.4444445) = 0.444445
str(0.04444445) = 0.0444445
str(0.004444445) = 0.00444444 // Why is 5 cut?
str(0.0004444445) = 0.000444445
str(0.00004444445) = 4.44445e-05 // Why is 5 cut?
str(0.5555555) = 0.555555 // Why is 5 cut?
str(0.05555555) = 0.0555556
str(0.005555555) = 0.00555556
str(0.0005555555) = 0.000555555 // Why is 5 cut?
str(0.00005555555) = 5.55555e-05 // Why is 5 cut?
str(0.6666665) = 0.666667
str(0.06666665) = 0.0666666 // Why is 5 cut?
str(0.006666665) = 0.00666666 // Why is 5 cut?
str(0.0006666665) = 0.000666666 // Why is 5 cut?
str(0.00006666665) = 6.66667e-05
str(0.7777775) = 0.777778
str(0.07777775) = 0.0777778
str(0.007777775) = 0.00777777 // Why is 5 cut?
str(0.0007777775) = 0.000777777 // Why is 5 cut?
str(0.00007777775) = 7.77777e-05 // Why is 5 cut?
str(0.8888885) = 0.888888 // Why is 5 cut?
str(0.08888885) = 0.0888889
str(0.008888885) = 0.00888888 // Why is 5 cut?
str(0.0008888885) = 0.000888888 // Why is 5 cut?
str(0.00008888885) = 8.88888e-05 // Why is 5 cut?
str(0.9999995) = 1
str(0.09999995) = 0.1
str(0.009999995) = 0.00999999 // Why is 5 cut?
str(0.0009999995) = 0.001
str(0.00009999995) = 0.0001
IV. In this observation, 7 digits of 5 (5555555) is multiplied by pow(10,n).
Again, this shows the extra-5 is treated unpredictably:
str(5555555000) = 5.55556e+09
str(555555500) = 5.55556e+08
str(55555550) = 5.55556e+07
str(5555555) = 5.55556e+06
str(5.555555) = 5.55556
str(0.5555555) = 0.555555 // Why is 5 cut?
str(0.05555555) = 0.0555556
str(0.005555555) = 0.00555556
str(0.0005555555) = 0.000555555 // Why is 5 cut?
str(0.00005555555)= 5.55555e-05 // Why is 5 cut?
$ Runsun Pan, PhD
$ libs: doctest , faces ( git ), offline doc ( git ),runscad.py( 1 , 2 , git );
$ tips: hash( 1 , 2 ), sweep , var , lerp , animGif
--
View this message in context: http://forum.openscad.org/Inconsistent-conversion-of-floating-number-to-string-at-7th-significant-digit-tp14350.html
Sent from the OpenSCAD mailing list archive at Nabble.com.
This appears to be the code in question, called when converting doubles into
strings:
https://github.com/openscad/openscad/blob/master/src/value.cc#L225-L238
The key is this comment:
// attempt to emulate Qt's QString.sprintf("%g"); from old OpenSCAD.
// see https://github.com/openscad/openscad/issues/158
That https://github.com/openscad/openscad/issues/158 contains details about
the thought-process that went into it.
Andrew.
--
View this message in context: http://forum.openscad.org/Inconsistent-conversion-of-floating-number-to-string-at-7th-significant-digit-tp14350p14354.html
Sent from the OpenSCAD mailing list archive at Nabble.com.
On Nov 10, 2015, at 13:31 PM, clothbot andrew@plumb.org wrote:
That https://github.com/openscad/openscad/issues/158 contains details about
the thought-process that went into it.
FYI: The test framework now has a better way of dealing with cross-platform rounding differences, so that aspect of the problem isn’t an issue any longer.
-Marius
@clothbot: Thx for the links. After reviewing them, however, I do believe
this is a different issue. What bothers me is not "how many digits" in
specific cases (like 8 vs 8.0000000004) nor "different platforms", but what
looks like a totally irregular manner of handling the number 5 --- sometimes
it is rounded up, sometimes it is rounded down, and for all the time I spent
in investigation, I couldn't figure out what rule OpenSCAD follows to decide
rounding up or down number 5.
clothbot wrote
This appears to be the code in question, called when converting doubles
into strings:
https://github.com/openscad/openscad/blob/master/src/value.cc#L225-L238
The key is this comment:
// attempt to emulate Qt's QString.sprintf("%g"); from old OpenSCAD.
// see https://github.com/openscad/openscad/issues/158
That https://github.com/openscad/openscad/issues/158 contains details
about the thought-process that went into it.
Andrew.
$ Runsun Pan, PhD
$ libs: doctest , faces ( git ), offline doc ( git ),runscad.py( 1 , 2 , git );
$ tips: hash( 1 , 2 ), sweep , var , lerp , animGif
--
View this message in context: http://forum.openscad.org/Inconsistent-conversion-of-floating-number-to-string-at-7th-significant-digit-tp14350p14375.html
Sent from the OpenSCAD mailing list archive at Nabble.com.
The round(x) function rounds away from zero. So round(0.5) == 1 and
round(-0.5) == -1.
The conversion from floating point to string is, in my opinion, broken. I
wrote a long explanation of why it is broken, and what I'd like to do
instead, in an earlier post. I should create an issue for this.
But briefly, I would like the float->string conversion to produce the
shortest floating point literal that, when read, exactlly reproduces the
original floating point number. This means no information is thrown away.
On 11 November 2015 at 16:04, runsun runsun@gmail.com wrote:
@clothbot: Thx for the links. After reviewing them, however, I do believe
this is a different issue. What bothers me is not "how many digits" in
specific cases (like 8 vs 8.0000000004) nor "different platforms", but what
looks like a totally irregular manner of handling the number 5 ---
sometimes
it is rounded up, sometimes it is rounded down, and for all the time I
spent
in investigation, I couldn't figure out what rule OpenSCAD follows to
decide
rounding up or down number 5.
clothbot wrote
This appears to be the code in question, called when converting doubles
into strings:
https://github.com/openscad/openscad/blob/master/src/value.cc#L225-L238
The key is this comment:
// attempt to emulate Qt's QString.sprintf("%g"); from old OpenSCAD.
// see https://github.com/openscad/openscad/issues/158
That https://github.com/openscad/openscad/issues/158 contains details
about the thought-process that went into it.
Andrew.
$ Runsun Pan, PhD
$ libs: doctest , faces ( git ), offline doc ( git ),runscad.py( 1 , 2 ,
git );
$ tips: hash( 1 , 2 ), sweep , var , lerp , animGif
--
View this message in context:
http://forum.openscad.org/Inconsistent-conversion-of-floating-number-to-string-at-7th-significant-digit-tp14350p14375.html
Sent from the OpenSCAD mailing list archive at Nabble.com.
OpenSCAD mailing list
Discuss@lists.openscad.org
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
--
View this message in context: http://forum.openscad.org/Inconsistent-conversion-of-floating-number-to-string-at-7th-significant-digit-tp14350p14389.html
Sent from the OpenSCAD mailing list archive at Nabble.com.
doug.moen wrote
The conversion from floating point to string is, in my opinion, broken. I
wrote a long explanation of why it is broken, and what I'd like to do
instead, in an earlier post. I should create an issue for this.
Consider the many many things (some are quite challenging) that
still need adding/fixing/improving in OpenSCAD, I'm not sure str(n)
is high (or even mid-) priority.
It seems almost easy to just port sprintf() to OpenSCAD and that's
that. But in an odd way, I almost relish the various handicaps OpenSCAD
throw at us. The subtle message is: DON'T use OpenSCAD for
conventional programming, don't do text processing (don't even dream
about adding regular expression to OpenSCAD), don't do general
file I/O (fopen, fread, fwrite, fclose), don't do advanced computations (I
was
toying with the masochistic(???) idea of writing a matrix inversion
algorithm
in OpenSCAD).
Sticks to making solids (STL) on OpenSCAD. A true geek would just mix-
language program (Java+OpenSCAD) to solve his practical problems and
leaving the masochism (matrix inversion in OpenSCAD) to the nut jobs.
(hmmm I am assuming no one had actually done it... have I called some
very smart person a nut job? ... oh wait... it seems really probably
possible
to write it... eh...)
(oops sorry for empty post previous)
--
View this message in context: http://forum.openscad.org/Inconsistent-conversion-of-floating-number-to-string-at-7th-significant-digit-tp14350p14391.html
Sent from the OpenSCAD mailing list archive at Nabble.com.
Advanced rounding algorithms may cast 0.5 to either 1 or 0 depending on
the preceding bit in the binary representation of the number.
See e.g. "Round half to even" https://en.wikipedia.org/wiki/Rounding
Just my $0.02
Tim
On 12.11.2015 0:04, runsun wrote:
@clothbot: Thx for the links. After reviewing them, however, I do believe
this is a different issue. What bothers me is not "how many digits" in
specific cases (like 8 vs 8.0000000004) nor "different platforms", but what
looks like a totally irregular manner of handling the number 5 --- sometimes
it is rounded up, sometimes it is rounded down, and for all the time I spent
in investigation, I couldn't figure out what rule OpenSCAD follows to decide
rounding up or down number 5.
clothbot wrote
This appears to be the code in question, called when converting doubles
into strings:
https://github.com/openscad/openscad/blob/master/src/value.cc#L225-L238
The key is this comment:
// attempt to emulate Qt's QString.sprintf("%g"); from old OpenSCAD.
// see https://github.com/openscad/openscad/issues/158
That https://github.com/openscad/openscad/issues/158 contains details
about the thought-process that went into it.
Andrew.
$ Runsun Pan, PhD
$ libs: doctest , faces ( git ), offline doc ( git ),runscad.py( 1 , 2 , git );
$ tips: hash( 1 , 2 ), sweep , var , lerp , animGif
--
View this message in context: http://forum.openscad.org/Inconsistent-conversion-of-floating-number-to-string-at-7th-significant-digit-tp14350p14375.html
Sent from the OpenSCAD mailing list archive at Nabble.com.
OpenSCAD mailing list
Discuss@lists.openscad.org
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
ctchin said "Consider the many many things (some are quite challenging) that
still need adding/fixing/improving in OpenSCAD, I'm not sure str(n)
is high (or even mid-) priority."
I agree, but I'm not saying that. OpenSCAD uses the same float->string
conversion everywhere, including the export to ASCII STL, and the export to
AMF. In the export case, severely truncating each float to 6 significant
digits often damages the mesh, so that OpenSCAD can't read STL files that
it itself has generated. (The conversion from CGAL rational numbers to
floats can also damage the mesh, but the float->string conversion is
responsible for most of the damage.) I'd like to fix this, and str(n) will
get fixed at the same time, as a bonus.
On 12 November 2015 at 00:16, ctchin c.t.chin@szu.edu.cn wrote:
doug.moen wrote
The conversion from floating point to string is, in my opinion, broken. I
wrote a long explanation of why it is broken, and what I'd like to do
instead, in an earlier post. I should create an issue for this.
Consider the many many things (some are quite challenging) that
still need adding/fixing/improving in OpenSCAD, I'm not sure str(n)
is high (or even mid-) priority.
It seems almost easy to just port sprintf() to OpenSCAD and that's
that. But in an odd way, I almost relish the various handicaps OpenSCAD
throw at us. The subtle message is: DON'T use OpenSCAD for
conventional programming, don't do text processing (don't even dream
about adding regular expression to OpenSCAD), don't do general
file I/O (fopen, fread, fwrite, fclose), don't do advanced computations (I
was
toying with the masochistic(???) idea of writing a matrix inversion
algorithm
in OpenSCAD).
Sticks to making solids (STL) on OpenSCAD. A true geek would just mix-
language program (Java+OpenSCAD) to solve his practical problems and
leaving the masochism (matrix inversion in OpenSCAD) to the nut jobs.
(hmmm I am assuming no one had actually done it... have I called some
very smart person a nut job? ... oh wait... it seems really probably
possible
to write it... eh...)
(oops sorry for empty post previous)
--
View this message in context:
http://forum.openscad.org/Inconsistent-conversion-of-floating-number-to-string-at-7th-significant-digit-tp14350p14391.html
Sent from the OpenSCAD mailing list archive at Nabble.com.
OpenSCAD mailing list
Discuss@lists.openscad.org
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Tim V. Shaporev wrote
Advanced rounding algorithms may cast 0.5 to either 1 or 0 depending on
the preceding bit in the binary representation of the number.
See e.g. "Round half to even" https://en.wikipedia.org/wiki/Rounding
Just my $0.02
Tim
Thx, Tim. But this doesn't explain those examples I raised in the first
post, where the rounding of 5 is handled differently even the preceding
number is the same.
$ Runsun Pan, PhD
$ libs: doctest , faces ( git ), offline doc ( git ),runscad.py( 1 , 2 , git );
$ tips: hash( 1 , 2 ), sweep , var , lerp , animGif
--
View this message in context: http://forum.openscad.org/Inconsistent-conversion-of-floating-number-to-string-at-7th-significant-digit-tp14350p14406.html
Sent from the OpenSCAD mailing list archive at Nabble.com.