|
From: Henry B. <hb...@pi...> - 2024-03-01 19:45:23
|
There's at least one library which provides for 'symbolic' NaN's in Rust: https://crates.io/crates/ananas "Put arbitrary bytes in your NaNs!" "The NaN payload is ignored no longer! Using ananas you can imbue entirely new meaning to your NaNs." "We can put and take out arbitrary bytes into NaNs, encoded as f32. Two bytes are stored in each f32 number" "NaNs are propagated and this maintains the payload" "This can produce strange behaviour when two NaNs meet, such as loss of commutativity" --- https://crates.io/crates/nan-tag "A library for NaN-tagged pointers in Rust. The library supports both borrowed and owned pointers" https://wingolog.org/archives/2011/05/18/value-representation-in-javascript-implementations "Initially, all JavaScript implementations used tagged pointers to represent JS values. This is a old trick that comes from the observation that allocated memory takes up at least 4 or 8 bytes, and are aligned in such a way that the least significant bit or three will be zero." "JavaScriptCore, the implementation used by WebKit, switched from tagged pointers to a "nan-boxed" format." --- https://crates.io/crates/boxing "An easy-to-use, cross-platform library for pointer and NaN boxing data - storing other data values in the unused portions of a float or pointer." --- https://crates.io/crates/nanval "A no_std, zero-dependency crate for the creation and handling of NaN-tagged 64-bit floating-point values" https://sean.cm/a/nan-boxing -----Original Message----- From: Richard Fateman <fa...@gm...> Sent: Mar 1, 2024 10:55 AM To: Matt Kaufmann <kau...@cs...> Cc: Stavros Macrakis <mac...@gm...>, Robert Dodier <rob...@gm...>, <gcl...@gn...>, <max...@li...> Subject: Re: [Maxima-discuss] +-Inf and NaN In order to use NaN mantissas as payloads for other data, I think we need something to break the abstraction. Are these features available in any lisp? I would think that given a NaN N, that we could look at its insides by (integer-decode-float N) but (following (setf sb-int:set-floating-point-modes :traps nil) SBCL says "Can't decode NaN or infinity") ... normally integer-decode-float would return 3 values. mantissa, exponent, sign. So fixing it would allow us to "read" the payload. Actually we may need 2, to decode a single and a double... integer-decode-single-float etc. Or maybe just (decode-double-nan...) to give just the mantissa. The reverse of this could look like a functional program... (construct-double-float-from-integers mantissa exponent sign) or destructive one(s) (insert-single-mantissa target value) (insert-single-exponent target value) ... etc. double.. or (setf (integer-mantissa N) value) These facilities would make it feasible to use NaNs for something.. Thanks. RJF . On Fri, Mar 1, 2024 at 8:52 AM Matt Kaufmann <kau...@cs... (mailto:kau...@cs...)> wrote: Hi Camm, Since this thread has discussed floating-point exceptions, I'll weigh in only by requesting that such behavior will continue to be configurable. Specifically, in ACL2 built using GCL 2.6.12 (Version_2_6_13pre131), where compilation uses safety 0, then evaluation of the following form at start-up gives the behavior I want -- in particular, an error when there is floating-point overflow or division by zero. (fpe:break-on-floating-point-exceptions :floating-point-overflow t :floating-point-invalid-operation t) For example, when I evaluate the definitions (defun f () (let ((y (* most-positive-double-float most-positive-double-float))) (= (- y y) 0.0d0))) and (defun g () (= (/ 0.0d0 0.0d0) 0.0d0)) and then compile f and g, then the evaluations of (f) and (g) both cause errors, which is what I want. (If f and g are compiled in gcl with safety 0 but are called without first calling fpe:break-on-floating-point-exceptions, then there is no error.) By the way, you asked, regarding other Lisps: > Can one access/manipulate nan at the lisp prompt level? See attached, which I think answers your question positively for LispWorks, Allegro CL, and CCL, but perhaps negatively for SBCL and CMUCL. Thanks, Matt Camm Maguire <ca...@ma... (mailto:ca...@ma...)> writes: > Greetings! > > Richard Fateman <fa...@gm... (mailto:fa...@gm...)> writes: > >> I think that using exactly the same argument conventions and names as the library would be best. >> so you overwrite one (or more) of the inputs, for the same reasons as mpfr does it, >> to save memory allocation when possible. >> >> Possible glitch: it assumes you will only pass arguments that are in memory, not on a stack. >> Thus for actual use you may need to have a functional style program interface that puts the >> arguments in memory. I think that mpfr number structures have a size [maximum length] and >> an actual size in use. So numbers and comparisons of them etc. must be >> done by mpfr. > > Yes this is the rub, and I believe the basic issues are the same with > floats as integers. GCL stores immediate fixnums in one format, other > fixnums in another, and bignums in a format directly accessible to gmp. > We could expose both the raw gmp interface and the 'functional' > interface which would load the first two into the third, but whether > done under the hood or by the user directly, there is nothing to > overwrite if fixnums are supplied as output arguments. At the C level > we have 5 bignum 'registers' which we do not expose to lisp, as if they > contain fixnums the logic pertaining to the same will fail. I suppose > an expert user could make use of the registers and be careful not to > refer to them until the gmp calculation is done. > > Take care, > >> RJF >> >> On Wed, Feb 28, 2024 at 12:55 PM Camm Maguire <ca...@ma... (mailto:ca...@ma...)> wrote: >> >> Greetings! >> >> Richard Fateman <fa...@gm... (mailto:fa...@gm...)> writes: >> >> > Several of us here have worked on arbitrary-precision floats in Lisp >> > (generally used for longer than double, though I suppose shorter could >> > also be specified...), and I think the real win would be to make use >> > of the mpfr library (written in C with various assembly-language hacks >> > for different CPUs). >> >> mpfr would be a straightforward extension to GCL, as we already use the >> gmp integer library, integrate it with our gbc/memory management, and >> export the functions at the lisp user level: >> >> >(gmp:mpz_mul most-positive-fixnum most-positive-fixnum) >> >> 85070591730234615847396907784232501249 >> >> The only sensible way to interface to a library like this is to keep all >> the function names and calling syntax the same. GMP is written with >> 'side-effects', i.e. destructive modification of the supplied arguments >> one or more of which are considered outputs. This is so the savvy user >> can avoid unnecessary allocations, which are effectively all that matter >> for performance. Lisp is so functionally oriented, however, that it >> seemed better to me to take only input variables as arguments. The >> natural alternative to the call above would take three arguments, >> overwrite the first, and return no values. Your thoughts? >> >> Take care, >> -- >> Camm Maguire ca...@ma... (mailto:ca...@ma...) >> ========================================================================== >> "The earth is but one country, and mankind its citizens." -- Baha'u'llah >> > > -- > Camm Maguire ca...@ma... (mailto:ca...@ma...) > ========================================================================== > "The earth is but one country, and mankind its citizens." -- Baha'u'llah |