I'm sure this has come up before, but in a cursory check I didn't see anyone else post an actual solution.
The FP value `nan` is handled in OpenSCAD in a very awkward manner. Firstoff, there's no constants for nan or inf, so lets work around that: NAN = acos(2); INF = 1/0; Secondly, the comparators for nan, while arguably true from an academic point of view, are almost completely useless from a programming perspective:  `is_num(NAN)` returns false. (Even though nan is of the same type as inf and 0.)  `NAN == NAN` returns false.  `NAN != NAN` returns true. Combined, these really make it very ugly to tell if a value is nan. The obvious tests are all useless: x = foo(); if (x==NAN) echo("This branch is NEVER executed for any value or type of x."); if (x!=NAN) echo("This branch is executed for ALL values of x, no matter the type."); As far as I can tell, the only way to detect NaN correctly is a complex construct like this: function is_nan(x) = !is_num(x) && !is_undef(x) && !is_string(x) && !is_list(x) && !(x<=INF) && is_undef(x[0]); The !(x<=INF) test disallows INF, INF, and booleans. The is_undef(x[0]) shows that x is not a range like [0:10].  Revar _______________________________________________ OpenSCAD mailing list [hidden email] http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org 
function is_nan(x) = (x != x) ? true : false; On February 7, 2020 at 00:25:59, Revar Desmera ([hidden email]) wrote:
_______________________________________________ OpenSCAD mailing list [hidden email] http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org 
Huh. Even shorter:
function is_nan(x) = x!=x;  Revar
_______________________________________________ OpenSCAD mailing list [hidden email] http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org 
On 07.02.20 11:02, Revar Desmera wrote:
> function is_nan(x) = x!=x; > That is somehow both elegant in its simplicity and horribly > twisted in its logic. Also nobody will claim any responsibility if it breaks at some point. If it makes sense to have that check, it would probably be better to actually implemented it in the core like the other test functions. The missing tokens are indeed a problem as that is one case where we can export files as CSG that can't be imported back. nan = 0/0; inf = 1/0; ninf = 1/0; echo(inf, ninf, nan); Just to highlight the point it's not an OpenSCAD invention: $ python3 Python 3.7.6 (default, Jan 19 2020, 22:34:52) [GCC 9.2.1 20200117] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import math >>> nan = math.nan >>> nan == nan False >>> nan != nan True >>> ciao, Torsten. _______________________________________________ OpenSCAD mailing list [hidden email] http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
 Torsten

Nan is pretty much defined to not be equal to itself, part of the floating point spec On Fri, 7 Feb 2020, 15:01 Torsten Paul, <[hidden email]> wrote: On 07.02.20 11:02, Revar Desmera wrote: _______________________________________________ OpenSCAD mailing list [hidden email] http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org 
In reply to this post by tp3
The IEEE floating point standard provides programming languages with two different options
when evaluating 0/0: either it raises an exception, or it returns the NaN value. Once you have a NaN value x, then x!=x must return true, according to IEEE. In Python, 0.0/0.0 raises an exception, it doesn't return NaN. In OpenSCAD, 0/0 returns NaN instead of raising an exception. Both languages are compatible with the IEEE standard in this circumstance. If you prefer your programming language to report an error when you have performed an illegal operation, rather than silently returning Nan or undef, then you probably want the Python semantics of 0/0 raising an exception. In my own 3D modelling language (Curv), arithmetic operations always report an error rather than return NaN. Since there's no way to generate a NaN, I don't need an is_nan() function, and it is guaranteed that x==x is always true and x!=x is always false. The only time I've actually seen this error reported was due to a bug in my program, that would otherwise have resulted in exporting an invalid STL file if the bug hadn't been fixed. My opinion is that disabling floating point exceptions and returning NaN for invalid arithmetic operations is something that should only be attempted by numerical analysts who know what they are doing. The semantics of NaN are too confusing, and propagating NaN values through an OpenSCAD program will probably result in bad geometry. I don't think that 0/0 should return NaN by default in a programming language that isn't targeted at high performance numerical analysis. Python gets this right. Doug Moen. On Fri, Feb 7, 2020, at 8:00 PM, Torsten Paul wrote: > On 07.02.20 11:02, Revar Desmera wrote: > > function is_nan(x) = x!=x; > > That is somehow both elegant in its simplicity and horribly > > twisted in its logic. > > Also nobody will claim any responsibility if it breaks at > some point. > > If it makes sense to have that check, it would probably be > better to actually implemented it in the core like the other > test functions. > > The missing tokens are indeed a problem as that is one case > where we can export files as CSG that can't be imported back. > > nan = 0/0; > inf = 1/0; > ninf = 1/0; > echo(inf, ninf, nan); > > Just to highlight the point it's not an OpenSCAD invention: > > $ python3 > Python 3.7.6 (default, Jan 19 2020, 22:34:52) > [GCC 9.2.1 20200117] on linux > Type "help", "copyright", "credits" or "license" for more information. > >>> import math > >>> nan = math.nan > >>> nan == nan > False > >>> nan != nan > True > >>> > > ciao, > Torsten. > > _______________________________________________ > OpenSCAD mailing list > [hidden email] > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org > _______________________________________________ OpenSCAD mailing list [hidden email] http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org 
In reply to this post by tp3
Yeah, I'd like to see a proper is_nan(x) builtin. And an is_range(x) as well.
IEEE754 is correct to specify that nan!=nan, as that is what you want when comparing results from two calculations. Most languages, however, also provide ways to test for nan. $ python3 >>> import math >>> nan = math.nan >>> nan is math.nan True >>> math.isnan(nan) True Even C/C++ has isnan(x). I'm fine with nan!=nan, so long as there exists a clean way to test for it. We need is_nan().  Revar > On Feb 7, 2020, at 12:00 PM, Torsten Paul <[hidden email]> wrote: > > On 07.02.20 11:02, Revar Desmera wrote: >> function is_nan(x) = x!=x; >> That is somehow both elegant in its simplicity and horribly >> twisted in its logic. > > Also nobody will claim any responsibility if it breaks at > some point. > > If it makes sense to have that check, it would probably be > better to actually implemented it in the core like the other > test functions. > > The missing tokens are indeed a problem as that is one case > where we can export files as CSG that can't be imported back. > > nan = 0/0; > inf = 1/0; > ninf = 1/0; > echo(inf, ninf, nan); > > Just to highlight the point it's not an OpenSCAD invention: > > $ python3 > Python 3.7.6 (default, Jan 19 2020, 22:34:52) > [GCC 9.2.1 20200117] on linux > Type "help", "copyright", "credits" or "license" for more information. > >>> import math > >>> nan = math.nan > >>> nan == nan > False > >>> nan != nan > True > >>> > > ciao, > Torsten. > > _______________________________________________ > OpenSCAD mailing list > [hidden email] > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org _______________________________________________ OpenSCAD mailing list [hidden email] http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org 
Here's an is_range function I came up with a while ago: is_range = function (x) !is_list(x) && !is_string(x) && !is_undef(x[0]);It works because you can access start,step,end as the first 3 "elements", but its not a list. On Fri, Feb 7, 2020 at 6:55 PM Revar Desmera <[hidden email]> wrote: Yeah, I'd like to see a proper is_nan(x) builtin. And an is_range(x) as well. _______________________________________________ OpenSCAD mailing list [hidden email] http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org 
Free forum by Nabble  Edit this page 