On Wed, Feb 21, 2024 at 7:54 AM Camm Maguire <c...@maguirefamily.org> wrote:
> Greetings, and thanks for your feedback! > > Raymond Toy <toy.raym...@gmail.com> writes: > > > When a is a floating-point number (= a a) should not be optimized to > > T. Likewise (/= a a) should not be optimized to NIL. I'm pretty sure > > IEEE754 says that NaN is never = to itself or another NaN or any other > > number. > > Why not? I agree the 'C' IEEE operator of similar name ('==') should be > left untouched, but the spec for common-lisp::= clearly implies that > the *same* NaN should be '= to itself, and even that different boxed > versions of the same bit patterns should be. I am suggesting that (/= a > a) not be a NaN detector, but to provide some other means (described > below). > I have no problem with alternative ways. Cmucl offers float-nan-p and float-signalling-nan-p functions. But since IEEE says NaN = NaN is always false, Lisp should support that as well. Cmucl supports this. I think sbcl does too. I'd try to test ecl and ccl, but I don't know how to turn off FP traps to create a NaN. > > I agree on 'staying close to the hardware', and one could just as well > say who cares on a practical violation of the spec. In general I am > sympathetic to such a point of view, but here it seems unnecessary. > I think CLHS isn't really super clear on IEEE floats. > > Lisp after all is just a bunch of hardware instructions with optional > type checking layered on top :-). #'car on a long-float should trigger > an error, and does at certain safety levels, but compile at safety 0, > and one gets the 'hardware' car which will return a value however > dubious it may be. The same could be the case for '=. Say NaN was > boxed with identical layout to a long-float, but with a different > type-word denoting something orthogonal to 'number, say 'ieee-special-64 > or some such. '= will then signal an error on nan input, except when > compiled at safety 0, in which case the NaN can be read as before in > boxed or unboxed form. The compiler would then simplify '= to t on > equivalent bindings, and we could use #'si::isnan or even (typep nan > 'ieee-special-64) as a detector. > I agree with what Robert says. Compilation safety here should change the computed results for valid inputs. > > > > > > We also have the following charming behavior: > > > > (typep nan 'long-float) ->t > > (typep nan '(long-float 0) ->nil > > (typep nan '(long-float * 0)) ->nil > > (typep nan '(or (long-float 0) (long-float * 0))) ->nil > > > > but the first and last types are of course identical. > > > > Isn't the last one a bug? Should the compiler convert (or (long-float > > 0) (long-float * 0)) to just long-float? > > > > I don't think so. (typep a '(or b c)) == (or (typep a b) (typep a c)) > FWIW, both cmucl and sbcl convert the type (or (double-float 0d0) (double-float * 0d0)) to just double-float and the last typep returns T. > > > > I'm not sure what the second and third cases returning nil really > > means in practice. I think even if you declare a function as only > > taking and returning (long-float 0), you can have operations return > > NaN, even if the inputs are non-negative floats. > > > > It means that NaN does not fit into a total ordering scheme of say > long-floats, and the type explicitly recognizes and denotes ordered > subsets. > Fair enough. > > > > If NaN was truly 'not a number', the numerical functions would trigger > > an error on input only when compiled with safety, and might be arranged > > > > I think I would defer to whatever the HW does and the floating point > > traps that are enabled. If the invalid trap is enabled, then we get > > errors. If the invalid trap is disabled, NaN gets returned. > > > > I think we can have our cacke and eat it too. We can still compile at > safety 0 and proceed with errors optionally triggered only when setting > FPE traps. But when interpreted or compiled with safety, standard type > errors would be triggered. > This seems ok. But (= nan nan) must return false. > > > > The subject also mentions +/= inf. Did you forget to mention issues > > with infinities? > > > > I am much less bothered by these, though they do make > most-positive-long-float meaningless. They are in fact quite useful in > bounds checking arithmetic in the compiler. Maybe > most-positive-long-float == +inf? > I don't think that would be really useful to anyone. It should be most positive finite value. > > Can anyone without too much effort summarize how other lisps handle > this? Can one access/manipulate nan at the lisp prompt level? > For cmucl you can do (set-floating-point-modes :traps nil) to disable all FP traps. Then (/ 0d0 0d0) returns a NaN. Sbcl uses sb-int::set-floating-point-modes instead. I don't know about the others. Oh, and sbcl says (type nan '(double-float 0d0)) is NIL. Cmucl says it's true. That's probably not right. > > Take care, > > > Take care, > > -- > > Camm Maguire > c...@maguirefamily.org > > > ========================================================================== > > "The earth is but one country, and mankind its citizens." -- > Baha'u'llah > > -- > Camm Maguire c...@maguirefamily.org > ========================================================================== > "The earth is but one country, and mankind its citizens." -- Baha'u'llah > -- Ray