Re: pi seems not to be a constant

"Pascal J. Bourguignon" <[email protected]>
Newsgroups gmane.lisp.clisp.general
Organization Informatimago
Message-ID <[email protected]>

On 20/10/15 21:29, Don Cohen wrote:
>    > If long-float-digits is changed and the "constants" are not adjusted
>    > then STANDARD PORTABLE CL code will break.
>
>    This is incomplete:
>
>    Not only the constants should be adjusted, but all the standard
>    portable CL code that has been compiled so far needs to be compiled
>    again, because defconstant constants can be inlined.
>
>    This is to avoid having to recompile and reload everything each time
>    you set ext:long-float-digits, that cl:pi is not a constant.
>
> If I understand correctly, you are saying that
> *If* pi, etc. were declared defconstant and changing precision changed
> it, then everything using pi would have to be recompiled.
> And depending on what you think it means to change precision, you
> might also want to reread and recompile all the code containing long
> constants.
>
> I think you agree with me that it's a bad idea to change the values of
> things that are declared defconstant.
Yes. Or to declare with defconstant variables that can change.

Also, remember that defconstant defines constant VARIABLES.
> I can't tell whether you think pi should not be defconstant because of
> this, or whether you agree with me that it should be declared
> defconstant and then not changed.
Read again the discussion.

The current state is not conforming but it's better than a conforming 
solution that would have to be much more complex.
> This doesn't solve the larger problem of constants in code.
> You probably don't want to replace 1l0 in your code with
> (read-from-string "1l0"), at leat if that code is to run many times.
> It's possible to write a macro (adjust-precision "1l0") that generates
> code that checks whether precision has been changed since it was last
> run (I hope that's cheap) and if so rereads the constant.  It could
> even keep a cache of values of different precisions.
1L0 is always 1L0, whatever the long-float-digits.

1234567890123456789012345678901234567890123456789012345678901234567890L0
may be read as different values when read with a different 
long-float-digits, but this remains conforming, since this is a behavior 
that already exists for the other floating point types and on all the 
implementations, and since the application knows when it changes the 
long-float-digits, so it may decide what to do about it.

In any case, the point is that in both cases, the precision of the 
concerned number is finite.

On the other hand, for π or e, the precision is infinite.  Therefore 
when you change long-float-digit, the long float value that should 
represent π or e (or any of the other transcendental numbers), is not 
the same anymore.

Again, in the case of e or other values, the implementation can deal 
with it, since it knows that it changed long-float-digits, it can 
re-compute a new approximation of its trancendantals with the new precision.

But the standard has a defect, in that it specifies PI to be a constant 
variable instead of being a function.
For a strict pedantic conformity, this means you would have to keep the 
precision of long-float fixed, and we'd have to provide a fifth subtype 
of long-float for variable precision. This would lead to complexities 
(and problems of conformity with programs that don't expect a fifth 
subtype of float!).

Therefore it's better to make CL:PI a non constant variable, and to 
rebind it when we change the precision.

We could also provide functions in EXT to provide values of 
transcendantals such as PI and E at the current or other precisions.

> While we're at it, I suggest that it would be a lot more convenient
> to programmatically control precision if there were a function to
> read long floats of precision n, e.g., (read-long "1l0" n), which
> returns the rough equivalent (I hope much more efficiently) of
>   (let ((p (ext:long-float-digits)))
>    (setf (ext:long-float-digits) n)
>    (prog1 (read-from-string "1l0") (setf (ext:long-float-digits) p)))
There it is:

(defun read-long (string n)
  (let ((p (ext:long-float-digits)))
     (setf (ext:long-float-digits) n)
     (prog1 (read-from-string "1l0") (setf (ext:long-float-digits) p))))
> It would also be nice if different threads could work in different
> default precisions.  For this purpose it seems better to make
> long-float-digits a regular special variable that can be rebound
> by any code and only affect the reads that are done with that binding.
> Of course, I don't propose that pi be changed or even rebound when
> long-float-digits is rebound.  But the rebinding will affect the value
> of (pi).
The binding of cl:pi could be thread-local.

> So now I'm proposing somewhat larger changes, but I think they
> make the resulting system quite a bit more useful.
> The underlying clisp seems perfectly well adapted to using different
> precisions under program control, but this facility is made
> unnecessarily inconvenient to use, in my opinion, by the current
> mechanism of (setf long-float-digits) and its adjustments, along with
> the lack of the read-long function and the functions like
> (pi &optional precision).

Notice that if you set long-float-digits, and save a bunch of long-float 
values computed with that precision, then you change long-float-digits, 
and use the saved values to further compute, then the resulting 
long-float will have the original precision. Therefore you can already 
have threads performing computations with different long-float 
precisions! (only take care of not reading new long floats or not using 
cl:pi or otherwise poluting your computing with long-float of a 
different precision).

-- 
__Pascal J. Bourguignon__
http://www.informatimago.com/


------------------------------------------------------------------------------
_______________________________________________
clisp-list mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/clisp-list
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.