From: rhat
Subject: Type Question
Date: 
Message-ID: <1106016750.903086.167170@c13g2000cwb.googlegroups.com>
Hi Everyone,
I've got a beginner's question about how numeric types are handled.
I'm writing a program that uses Newton's Approximation method to find
the roots of functions
(http://www.sosmath.com/calculus/diff/der07/der07.html if you care that
much), so I'm doing a lot of math with fractions.

Unfortunately, lisp (I've tried clisp 2.33.1 and cmucl 18e) keeps
handling these fractions not as finite-precision floating point numbers
(which I was kinda hoping for), but as unlimited-precision ratios
(seriously huge ones too, with 30+ digits). These huge ratios eat up
all available memory, and cause a crash, so I'd like them to be handled
as finite-precision numbers instead (complex floating point numbers in
particular).

Is there some way that I can force lisp to handle these numbers not at
ratios, but as finite floats (or finite complex floats)?

From: Pascal Bourguignon
Subject: Re: Type Question
Date: 
Message-ID: <87vf9vh23i.fsf@thalassa.informatimago.com>
"rhat" <·········@gmail.com> writes:

> Hi Everyone,
> I've got a beginner's question about how numeric types are handled.
> I'm writing a program that uses Newton's Approximation method to find
> the roots of functions
> (http://www.sosmath.com/calculus/diff/der07/der07.html if you care that
> much), so I'm doing a lot of math with fractions.
> 
> Unfortunately, lisp (I've tried clisp 2.33.1 and cmucl 18e) keeps
> handling these fractions not as finite-precision floating point numbers
> (which I was kinda hoping for), but as unlimited-precision ratios
> (seriously huge ones too, with 30+ digits). 

30 digits ain't nothing.  Lisp can easily handle numbers with 100000
digits, and the limit is really really high.


> These huge ratios eat up all available memory, and cause a crash, so
> I'd like them to be handled as finite-precision numbers instead
> (complex floating point numbers in particular).

Oh, you want wrong results. Yes, for physics it'd be ok I guess.  But
for math...

 
> Is there some way that I can force lisp to handle these numbers not at
> ratios, but as finite floats (or finite complex floats)?

Yes, don't give ratios, give floating point numbers. 
Write 0.1 instead of (/ 1 10).
Write (/ x 2.0) instead of (/ x 2).
etc.

-- 
__Pascal Bourguignon__                     http://www.informatimago.com/
Cats meow out of angst
"Thumbs! If only we had thumbs!
We could break so much!"
From: rhat
Subject: Re: Type Question
Date: 
Message-ID: <1106020528.624763.246550@f14g2000cwb.googlegroups.com>
Wow, thanks, that worked just fine! (now I wonder why I didn't think to
do that =P )
From: Mario S. Mommer
Subject: Re: Type Question
Date: 
Message-ID: <fzllarkv2w.fsf@germany.igpm.rwth-aachen.de>
Pascal Bourguignon <····@mouse-potato.com> writes:
> "rhat" <·········@gmail.com> writes:
>> These huge ratios eat up all available memory, and cause a crash, so
>> I'd like them to be handled as finite-precision numbers instead
>> (complex floating point numbers in particular).
>
> Oh, you want wrong results. Yes, for physics it'd be ok I guess.  But
> for math...

Oh please.

>> Is there some way that I can force lisp to handle these numbers not at
>> ratios, but as finite floats (or finite complex floats)?
>
> Yes, don't give ratios, give floating point numbers. 
> Write 0.1 instead of (/ 1 10).
> Write (/ x 2.0) instead of (/ x 2).
> etc.

To the OP: 2.0 is usually single precission, while 2.0d0 is double
precission.

Take a look (a look! this is too dry for a beginner, but can give you
some ideas) at

http://www.ai.mit.edu/projects/iiip/doc/CommonLISP/HyperSpec/Body/sec_the_numbers_dictionary.html


To ensure some number is coerced to the correct floating point format,
you can use

    (float yournumber prototype)

where prototype is some example. So for instance

    (float pi 0.0)

gives you a single precission version of Pi, and

    (sqrt (float 1/3 0.0d0))

gives you the square root of 0.3333333333333333d0. &.c.
From: Trent Buck
Subject: Re: Type Question
Date: 
Message-ID: <20050118220224.5cf869f0@harpo.marx>
Up spake Mario S. Mommer:
> > Oh, you want wrong results. Yes, for physics it'd be ok I guess.  But
> > for math...
> 
> Oh please.

<OT>
  I can't resist.

    3 is prime.
    5 is prime.
    7 is prime.
    9 is an experimental error.
    11 is prime.
    13 is prime.
    The data supports the hypothesis.

  (What, you want more than the punchline?)
</>

Why does CL parse 0.5 differently to (/ 2)?  I would have expected it to
say "Oh yes, that can be expressed exactly as a rational." and require
the user to (more) explicitly coerce it to a float.

-- 
-trent
Every program has two purposes -- one for which it was written and
another for which it wasn't.
From: Barry Margolin
Subject: Re: Type Question
Date: 
Message-ID: <barmar-E51E20.09032318012005@comcast.dca.giganews.com>
In article <·······················@harpo.marx>,
 Trent Buck <·········@tznvy.pbz> wrote:

> Why does CL parse 0.5 differently to (/ 2)?  I would have expected it to
> say "Oh yes, that can be expressed exactly as a rational." and require
> the user to (more) explicitly coerce it to a float.

When you type a number as a decimal fraction, you're implying that this 
is an approximation that you want represented as a floating point.  For 
instance, you might do:

(defconstant *pi* 3.14159)

If you want a number you enter to be taken as an exact rational, enter 
it as a fraction:

(defconstant *half* 1/2)

So we provide two ways for you to enter numbers, to get two different 
results.

(defconstant *about-half* .5)

Why do you think it would be preferable for it to second-guess you?

-- 
Barry Margolin, ······@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
From: Jens Axel Søgaard
Subject: Re: Type Question
Date: 
Message-ID: <41ed4235$0$261$edfadb0f@dread12.news.tele.dk>
Barry Margolin wrote:

> (defconstant *pi* 3.14159)

I can't resist:

   The primary purpose of the DATA statement is to give
   names to constants; instead of referring to pi
   as 3.141592653589793 at every appearance, the
   variable PI can be given that value with a DATA
   statement and used instead of the longer form of the
   constant. This also simplifies modifying the program,
   should the value of pi change.

   -- FORTRAN manual for Xerox Computers

-- 
Jens Axel Søgaard
From: ·········@cern.ch
Subject: Re: Type Question
Date: 
Message-ID: <yzollar2ah9.fsf@cern.ch>
Trent> Why does CL parse 0.5 differently to (/ 2)?  I would have
Trent> expected it to say "Oh yes, that can be expressed exactly as a
Trent> rational." and require the user to (more) explicitly coerce it
Trent> to a float.

Why would you "expect" that 0.5 and (/ 2) are both "parsed" into a
rational? Is there anything in the spec that would indicate such
behaviour?  To quote a comp.lang.lisp-oldtimer:

   If this isn't what you expected, please adjust your expectations.

Just for the record:

0.5 is read as a SINGLE-FLOAT number, unless
*READ-DEFAULT-FLOAT-FORMAT* has been changed from its default.

(/ 2) is read as a list with elements / and 2.

0.5d0 is read as a DOUBLE-FLOAT number.

1/2 is read as a rational.

Ole
From: Trent Buck
Subject: Re: Type Question
Date: 
Message-ID: <20050119002318.46e15e50@harpo.marx>
Up spake ·········@cern.ch:
> Trent> Why does CL parse 0.5 differently to (/ 2)?  I would have
> Trent> expected it to say "Oh yes, that can be expressed exactly as a
> Trent> rational." and require the user to (more) explicitly coerce it
> Trent> to a float.
> 
> Why would you "expect" that 0.5 and (/ 2) are both "parsed" into a
> rational? Is there anything in the spec that would indicate such
> behaviour? 

I was unclear.  By "expectation" I meant

	1) Assume that Lisp has a perfect system.[0]

	2) Assume that the formatting of a literal number (e.g. "0.5"
           vs.  "1/2") should not affect how it is stored internally
           (after being read in) in an perfect system.

	   (Similar to how symbols are not treated any differently if
	    they are lowercase, UPPERCASE or MiXeD.)

        1 AND 2 IMPLIES 3

	3) Lisp does not care if you write "0.5" or "1/2" -- it will use
           the most accurate, reasonable form.  You can use the operator
           FOO to redefine what is `resonable', or BAR to force a
           particular literal to be stored in a particular way.

Of course, what I'm *really* interested in is whether (2) is actually
correct, and *why*.

[0] That's right, it's an ideal system; the Real World can only
    approximate it.  Do you want to go on being pedantic, or would you
    prefer to discuss the question to hand?

-- 
-trent
For is it not written, wheresoever two or three are gathered together,
yea they will perform the Parrot Sketch. -- Rob
From: Pascal Bourguignon
Subject: Re: Type Question
Date: 
Message-ID: <87llaqhkzg.fsf@thalassa.informatimago.com>
Trent Buck <·········@tznvy.pbz> writes:

> Up spake ·········@cern.ch:
> > Trent> Why does CL parse 0.5 differently to (/ 2)?  I would have
> > Trent> expected it to say "Oh yes, that can be expressed exactly as a
> > Trent> rational." and require the user to (more) explicitly coerce it
> > Trent> to a float.
> > 
> > Why would you "expect" that 0.5 and (/ 2) are both "parsed" into a
> > rational? Is there anything in the spec that would indicate such
> > behaviour? 
> 
> I was unclear.  By "expectation" I meant
> 
> 	1) Assume that Lisp has a perfect system.[0]

Lisp perhaps has it.  But Common-Lisp is a practical lisp, which
specifies stuff to give efficient implementations, not perfect ones.


-- 
__Pascal Bourguignon__                     http://www.informatimago.com/
You never feed me.
Perhaps I'll sleep on your face.
That will sure show you.
From: Thomas A. Russ
Subject: Re: Type Question
Date: 
Message-ID: <ymipt022p0a.fsf@sevak.isi.edu>
Trent Buck <·········@tznvy.pbz> writes:

> 	2) Assume that the formatting of a literal number (e.g. "0.5"
>            vs.  "1/2") should not affect how it is stored internally
>            (after being read in) in an perfect system.
> 
> 	   (Similar to how symbols are not treated any differently if
> 	    they are lowercase, UPPERCASE or MiXeD.)

But would you also expect that the internal representation of "2" and
"2.0" would be the same?  Or would you expect that

  (type-of 2)    =>  FIXNUM
  (type-of 2.0)  =>  FLOAT



-- 
Thomas A. Russ,  USC/Information Sciences Institute
From: Paul F. Dietz
Subject: Re: Type Question
Date: 
Message-ID: <W96dnYZLHbgJIHDcRVn-2g@dls.net>
Thomas A. Russ wrote:

>  Or would you expect that
> 
>   (type-of 2)    =>  FIXNUM

Not in Common Lisp! :)

	Paul
From: Thomas A. Russ
Subject: Re: Type Question
Date: 
Message-ID: <ymioefm2ous.fsf@sevak.isi.edu>
Trent Buck <·········@tznvy.pbz> writes:


> 
> Up spake ·········@cern.ch:
> > Trent> Why does CL parse 0.5 differently to (/ 2)?  I would have
> > Trent> expected it to say "Oh yes, that can be expressed exactly as a
> > Trent> rational." and require the user to (more) explicitly coerce it
> > Trent> to a float.


> 	2) Assume that the formatting of a literal number (e.g. "0.5"
>            vs.  "1/2") should not affect how it is stored internally
>            (after being read in) in an perfect system.
> 
> 	   (Similar to how symbols are not treated any differently if
> 	    they are lowercase, UPPERCASE or MiXeD.)

And what would you have the system do with "0.333"

Would you want it to guess that this is supposed to be an extremely lazy
way of saying 1/3  or an exact way of saying 333/1000 ?  Short of having
a mind reading parser, it would be rather difficult to get Lisp, clever
though it is, to figure out what you meant, since any finite decimal
fraction has an exact representation as a rational number.

-- 
Thomas A. Russ,  USC/Information Sciences Institute
From: Cameron MacKinnon
Subject: Re: Type Question
Date: 
Message-ID: <4a2dnepwmsEDS3DcRVn-rg@golden.net>
Thomas A. Russ wrote:
> Trent Buck <·········@tznvy.pbz> writes:
> 
> 
>>	2) Assume that the formatting of a literal number (e.g. "0.5"
>>           vs.  "1/2") should not affect how it is stored internally
>>           (after being read in) in an perfect system.

> And what would you have the system do with "0.333"
> 
> Would you want it to guess that this is supposed to be an extremely lazy
> way of saying 1/3  or an exact way of saying 333/1000 ?  Short of having
> a mind reading parser, it would be rather difficult to get Lisp, clever
> though it is, to figure out what you meant, since any finite decimal
> fraction has an exact representation as a rational number.

Short of having a mind reading parser, it might not be too difficult to 
implement (exactly 0.333) and (approximately 0.333).

Barring that, I doubt that any rational (sorry) users expect 0.333 to be 
promoted to 333/1000, because they're NOT equivalent. This is a vastly 
different thing from expecting 0.5 to be equivalent to 1/2, because they 
ARE the same number.
From: Cameron MacKinnon
Subject: Re: Type Question
Date: 
Message-ID: <JLOdnUG39uWZRXDcRVn-ig@golden.net>
Cameron MacKinnon wrote:
> Barring that, I doubt that any rational (sorry) users expect 0.333 to be 
> promoted to 333/1000, because they're NOT equivalent.

Umm... "to be promoted to 1/3" - but everyone figured that out from 
context, right?
From: Trent Buck
Subject: Re: Type Question
Date: 
Message-ID: <20050119201422.302fd485@harpo.marx>
Up spake Cameron MacKinnon:
> Common Lisp overloads number input  representation -- 1/2 says
> "exact", 0.5 says either (depending on whom you listen to) "0.5 or a
> close approximation thereto" or "an interval which contains 0.5".
> 
> This is, of course, a bad idea. The three proofs are that new users are 
> often confused by this behaviour (because it doesn't accord with the 
> notation that everyone uses in the real world), experienced users 
> continue to argue over the approximation/interval interpretations, and 
> it causes some people post oddities suggesting that 0.5 and 1/2 aren't 
> the same number.
>
> [...]
>
> Short of having a mind reading parser, it might not be too difficult to 
> implement (exactly 0.333) and (approximately 0.333).
> 
> Barring that, I doubt that any rational (sorry) users expect 0.333 to be 
> promoted to 1/3, because they're NOT equivalent. This is a vastly 
> different thing from expecting 0.5 to be equivalent to 1/2, because they 
> ARE the same number.

Thanks, this is what I tried to say in the first place.  If I'm not the
most communicative of writers, at least I can be understood by those who
are.

-- 
-trent
A monk asked Tozan when he was weighing some flax: `What is Buddha?'
Tozan said: `This flax weighs three pounds.'
From: Matthew Danish
Subject: Re: Type Question
Date: 
Message-ID: <877jlzop3d.fsf@mapcar.org>
Cameron MacKinnon <··········@clearspot.net> writes:
> Short of having a mind reading parser, it might not be too difficult
> to implement (exactly 0.333) and (approximately 0.333).

I don't see how this could ever be implemented.  What is exactly
0.333?  333/1000 that's what!  You're asking for some form of DWIM,
which is a "feature" generally and explicitly not found in CL.

> Barring that, I doubt that any rational (sorry) users expect 0.333 to
> be promoted to 333/1000, because they're NOT equivalent. This is a
> vastly different thing from expecting 0.5 to be equivalent to 1/2,
> because they ARE the same number.

You're making your argument based on the fact that 1/3 is a repeating
decimal in base 10 and 1/2 is not.  But that is not necessarily the
case in other bases, such as base 2.

-- 
;; Matthew Danish -- user: mrd domain: cmu.edu
;; OpenPGP public key: C24B6010 on keyring.debian.org
From: Cameron MacKinnon
Subject: Re: Type Question
Date: 
Message-ID: <vbudnW8Ncejt2GTcRVn-gg@golden.net>
Matthew Danish wrote:
> Cameron MacKinnon <··········@clearspot.net> writes:
> 
>>Short of having a mind reading parser, it might not be too difficult
>>to implement (exactly 0.333) and (approximately 0.333).
> 
> 
> I don't see how this could ever be implemented.  What is exactly
> 0.333?  333/1000 that's what!  You're asking for some form of DWIM,
> which is a "feature" generally and explicitly not found in CL.

Nope. Above I'm arguing for less DWIM than we have now. Currently, 
programmers entering 0.333 mean one of four things:
- the number 0.333
- an approximate number 0.3325 <= x < 0.3335
- a small interval containing 0.333
- a number very close to 0.333, give or take a digit in the 17th place

Regardless of original intent, Lisp takes the decimal as license to 
store an approximation, the accuracy of which may degrade as a result of 
subsequent inexact operations performed on it. Further, standard 
arithmetic operations are overloaded to operate on mixed exact and 
inexact operands, producing inexact results. Through a process that a 
cynic would regard as more miraculous than planned, the usual result is 
a close-enough-to-satisfy-the-user answer, regardless of which of the 
original four things the programmer meant.

You may say that other languages do this too, that the ANSI standard 
dictates this behaviour, that programmers who misuse numerics because 
they don't read the instructions are culpable, and that the current 
notation is awfully terse and convenient for those who understand the 
exact ramifications of mixed binary/decimal/exact/inexact numerics. All 
true.

But I think that sloppy numerics is one area where there's still room 
for improvement in Lisp, and programming languages in general. Lisp 
eliminates whole classes of non-numeric bugs that other languages are 
plagued by. Lisp is one of the better substrates on which to build great 
mathematical machines. But Lisp, out of the box, suffers from many of 
the same numerics deficiencies and misuses as other more pedestrian 
languages.

Thomas Russ wrote a very good analysis of some of the possibilities, 
which I unfortunately didn't have time to respond to. I haven't 
formulated in-depth plans of exactly how I think numerics could be 
improved, but I think there's room to make a more expressive language 
which reduces the pain caused by current sloppy numeric programming, 
doesn't reduce the expression available to skilled practitioners, and 
allows all of us more confidence in the likely correctness of the 
numeric code written in it.

> You're making your argument based on the fact that 1/3 is a repeating
> decimal in base 10 and 1/2 is not.  But that is not necessarily the
> case in other bases, such as base 2.

I'm ignoring this bit because it referred to a typo on my part which I 
corrected in a subsequent post.
From: ·········@cern.ch
Subject: Re: Type Question
Date: 
Message-ID: <yzozmz6u22v.fsf@cern.ch>
Trent> Why does CL parse 0.5 differently to (/ 2)?  I would have
Trent> expected it to say "Oh yes, that can be expressed exactly as a
Trent> rational." and require the user to (more) explicitly coerce it
Trent> to a float.

>> Why would you "expect" that 0.5 and (/ 2) are both "parsed" into a
>> rational? Is there anything in the spec that would indicate such
>> behaviour? 

Trent> I was unclear.  By "expectation" I meant
Trent> 1) Assume that Lisp has a perfect system.[0]

What do you mean by "perfect", perhaps something like "ideal"? CL is a
very powerful but *practical* system for programming computers. This
has very little to do with *ideal* representations of maths. In maths,
the rational numbers form a subset of the real numbers. In CL (or any
practical programming system), rational numbers are strictly disjoint
from floating point numbers.

Trent> 2) Assume that the formatting of a literal number (e.g. "0.5"
Trent>    vs.  "1/2") should not affect how it is stored internally
Trent>    (after being read in) in an perfect system.

I don't agree that "0.5" and "1/2" are just different formatting of
the same literal number. Maybe so if we were doing maths on a
blackboard, but not when interacting with a computer: "0.5" screams
"floating point", "1/2" will confuse just about everybody except
lispers.

Trent> 	   (Similar to how symbols are not treated any differently if
Trent> 	   they are lowercase, UPPERCASE or MiXeD.)

(I'm sure you know that this isn't really true; the casing behavior of
the   CL reader is indeed configurable.)

Trent> Of course, what I'm *really* interested in is whether (2) is
Trent> actually correct, and *why*.

(2) is wrong because CL deals with programming real computers
implemented on actual hardware. Hardware doesn't have "real number
units", but most of them do have "floating point units".

Trent> [0] That's right, it's an ideal system; the Real World can only
Trent> approximate it.

I beg to differ: The real world doesn't approximate anything; it is an
exact representation of itself. Don't think of floating point numbers
as approximations the real numbers; they are exact representations of
a subset of the rational numbers. Ok, sometimes you have to pick the
floating point number that is closest to a real number like PI, but
otherwise everything inside your computer is exact.

Trent> Do you want to go on being pedantic, or would you prefer to
Trent> discuss the question to hand?

Who is pedantic? My rhetoric was perhaps a bit overdone, but the quote
fitted all too well to be missed:-) Seriously, you shouldn't miss the
importance of CL behaving according to a *specification* (as opposed
to the whims of any particular *implementation*, see any of
tcl/perl/python/ruby/guile). 

So you knew about the ANSI spec already? I guess I've insulted your
intellect even more now by explaining about FPUs:-)

Ole
From: Sam Steingold
Subject: Re: Type Question
Date: 
Message-ID: <uacr67jbd.fsf@gnu.org>
> *  <·········@prea.pu> [2005-01-18 17:36:08 +0100]:
>
> Don't think of floating point numbers as approximations the real
> numbers; they are exact representations of a subset of the rational
> numbers.

if this were the case, FP arithmetics would have been exact, which it is not
(cf <http://www.lisp.org/HyperSpec/Body/convar_short-_tive-epsilon.html>)

-- 
Sam Steingold (http://www.podval.org/~sds) running w2k
<http://www.camera.org> <http://www.iris.org.il> <http://www.memri.org/>
<http://www.mideasttruth.com/> <http://www.honestreporting.com>
Yeah, yeah, I love cats too... wanna trade recipes?
From: Christophe Rhodes
Subject: Re: Type Question
Date: 
Message-ID: <sqhdle4b0u.fsf@cam.ac.uk>
Sam Steingold <···@gnu.org> writes:

>> *  <·········@prea.pu> [2005-01-18 17:36:08 +0100]:
>>
>> Don't think of floating point numbers as approximations the real
>> numbers; they are exact representations of a subset of the rational
>> numbers.
>
> if this were the case, FP arithmetics would have been exact, which it is not

No, that's not true.  They are exact representations of a subset of
the rational numbers; that set is not closed under the action of the
various exact arithmetic operations; the constraint that 
<member> x <member> -> <member> where x is an arithmetic operator 
implies that some FP arithmetic results will be inexact.
From: Sam Steingold
Subject: Re: Type Question
Date: 
Message-ID: <uis5u5lae.fsf@gnu.org>
> * Christophe Rhodes <·····@pnz.np.hx> [2005-01-18 22:39:45 +0000]:
>
> Sam Steingold <···@gnu.org> writes:
>
>>> *  <·········@prea.pu> [2005-01-18 17:36:08 +0100]:
>>>
>>> Don't think of floating point numbers as approximations the real
>>> numbers; they are exact representations of a subset of the rational
>>> numbers.
>>
>> if this were the case, FP arithmetics would have been exact, which it is not
>
> No, that's not true.  They are exact representations of a subset of
> the rational numbers; that set is not closed under the action of the
> various exact arithmetic operations; the constraint that <member> x
> <member> -> <member> where x is an arithmetic operator implies that
> some FP arithmetic results will be inexact.

This means that the model "FP represents a rational" is a bad model -
just what I said.

A much better model is "FP represents a segment on a real line".


-- 
Sam Steingold (http://www.podval.org/~sds) running w2k
<http://www.camera.org> <http://www.iris.org.il> <http://www.memri.org/>
<http://www.mideasttruth.com/> <http://www.honestreporting.com>
You think Oedipus had a problem -- Adam was Eve's mother.
From: Christophe Rhodes
Subject: Re: Type Question
Date: 
Message-ID: <sqd5w151tn.fsf@cam.ac.uk>
Sam Steingold <···@gnu.org> writes:

>> * Christophe Rhodes <·····@pnz.np.hx> [2005-01-18 22:39:45 +0000]:
>>
>> Sam Steingold <···@gnu.org> writes:
>>
>>> if this were the case, FP arithmetics would have been exact, which it is not
>>
>> No, that's not true.  They are exact representations of a subset of
>> the rational numbers; that set is not closed under the action of the
>> various exact arithmetic operations; the constraint that <member> x
>> <member> -> <member> where x is an arithmetic operator implies that
>> some FP arithmetic results will be inexact.
>
> This means that the model "FP represents a rational" is a bad model -
> just what I said.
>
> A much better model is "FP represents a segment on a real line".

I'm not convinced it is much better, because floating point arithmetic
doesn't obey the interval arithmetic rules you'd expect from that
point of view either.

Christophe
From: ·········@cern.ch
Subject: Re: Type Question
Date: 
Message-ID: <yzooefl20js.fsf@cern.ch>
>> Don't think of floating point numbers as approximations the real
>> numbers; they are exact representations of a subset of the rational
>> numbers.

Sam> if this were the case, FP arithmetics would have been exact,
Sam> which it is not

I don't follow your logic here; why does "FP arithmetics would have
been exact" follow from "FP numbers are exact representations of a
subset of the rational numbers"?

On the other hand, if A, B and C=A+B are all rational numbers
supported by the actual FP representation, isn't (= C (+ A B)) true?
I'd admit I haven't thought too hard about the other arithmetic
operations (#'- #'* #'/).

Ole
From: Cameron MacKinnon
Subject: Re: Type Question
Date: 
Message-ID: <csGdnV-pu4CRSHDcRVn-rw@golden.net>
Trent Buck wrote:
> I was unclear.  By "expectation" I meant
> 
> 	1) Assume that Lisp has a perfect system.[0]
> 
> 	2) Assume that the formatting of a literal number (e.g. "0.5"
>            vs.  "1/2") should not affect how it is stored internally
>            (after being read in) in an perfect system.
...
> Of course, what I'm *really* interested in is whether (2) is actually
> correct, and *why*.

(2) is incorrect, because Common Lisp overloads number input 
representation -- 1/2 says "exact", 0.5 says either (depending on whom 
you listen to) "0.5 or a close approximation thereto" or "an interval 
which contains 0.5"

This is, of course, a bad idea. The three proofs are that new users are 
often confused by this behaviour (because it doesn't accord with the 
notation that everyone uses in the real world), experienced users 
continue to argue over the approximation/interval interpretations, and 
it causes some people post oddities suggesting that 0.5 and 1/2 aren't 
the same number.

Scheme has an explicit mechanism for tagging numbers as being either 
exact or approximations, and numeric contagion when performing 
operations works about as one would expect.

Be that as it may, Common Lisp's interpretation of numbers (according to 
how they are written) is not open to interpretation -- it is written in 
to the standard.
From: Rahul Jain
Subject: Re: Type Question
Date: 
Message-ID: <878y6qavmo.fsf@nyct.net>
Cameron MacKinnon <··········@clearspot.net> writes:

> Scheme has an explicit mechanism for tagging numbers as being either
> exact or approximations, and numeric contagion when performing
> operations works about as one would expect.

Good thing CL works the same in these regards.

-- 
Rahul Jain
·····@nyct.net
Professional Software Developer, Amateur Quantum Mechanicist
From: Christophe Rhodes
Subject: Re: Type Question
Date: 
Message-ID: <sq8y6p51qn.fsf@cam.ac.uk>
Rahul Jain <·····@nyct.net> writes:

> Cameron MacKinnon <··········@clearspot.net> writes:
>
>> Scheme has an explicit mechanism for tagging numbers as being either
>> exact or approximations, and numeric contagion when performing
>> operations works about as one would expect.
>
> Good thing CL works the same in these regards.

No it doesn't.  In Scheme, inexactitude is mostly orthogonal to
numeric value representation.

Christophe
From: Rahul Jain
Subject: Re: Type Question
Date: 
Message-ID: <87651o3wqz.fsf@nyct.net>
Christophe Rhodes <·····@cam.ac.uk> writes:

> Rahul Jain <·····@nyct.net> writes:
>
>> Cameron MacKinnon <··········@clearspot.net> writes:
>>
>>> Scheme has an explicit mechanism for tagging numbers as being either
>>> exact or approximations, and numeric contagion when performing
>>> operations works about as one would expect.
>>
>> Good thing CL works the same in these regards.
>
> No it doesn't.  In Scheme, inexactitude is mostly orthogonal to
> numeric value representation.

Yes, the CL forces you to assume that inexact rationals (see below about
irrationals) have a denominator which is a power of a specific base. I
suppose having a type where the denominator is of a specific integral
type, e.g. (unsigned-byte 32) would be useful in this regard. Don't know
if it'll really improve performance much.

Maybe you're talking about using expressions similar to '(+ (LOG 15)
(SIN 15)) as numeric values? I'd rather something more powerful like
weyl or maxima for such tasks, but maybe such a library could be
integrated into some implementations...

-- 
Rahul Jain
·····@nyct.net
Professional Software Developer, Amateur Quantum Mechanicist
From: Jens Axel Søgaard
Subject: Re: Type Question
Date: 
Message-ID: <41ee0b9e$0$233$edfadb0f@dread12.news.tele.dk>
Cameron MacKinnon wrote:

> Scheme has an explicit mechanism for tagging numbers as being either 
> exact or approximations, and numeric contagion when performing 
> operations works about as one would expect.

Not everybody thinks Scheme has found the ideal solution.
See "Cleaning up the Tower: Numbers in Scheme"

     <http://repository.readscheme.org/ftp/papers/sw2004/egner.pdf>

-- 
Jens Axel Søgaard
From: Cameron MacKinnon
Subject: Re: Type Question
Date: 
Message-ID: <6YmdnQwo08lFt3PcRVn-ow@golden.net>
Jens Axel S�gaard wrote:
> Cameron MacKinnon wrote:
> 
>> Scheme has an explicit mechanism for tagging numbers as being either 
>> exact or approximations, and numeric contagion when performing 
>> operations works about as one would expect.
> 
> 
> Not everybody thinks Scheme has found the ideal solution.
> See "Cleaning up the Tower: Numbers in Scheme"
> 
>     <http://repository.readscheme.org/ftp/papers/sw2004/egner.pdf>
> 

Thanks, that was good food for thought.
From: Thomas A. Russ
Subject: Re: Type Question
Date: 
Message-ID: <ymillap2pm6.fsf@sevak.isi.edu>
Cameron MacKinnon <··········@clearspot.net> writes:

> 
> Trent Buck wrote:
> > I was unclear.  By "expectation" I meant
> > 
> > 	1) Assume that Lisp has a perfect system.[0]
> > 
> > 	2) Assume that the formatting of a literal number (e.g. "0.5"
> >            vs.  "1/2") should not affect how it is stored internally
> >            (after being read in) in an perfect system.
> ...
> > Of course, what I'm *really* interested in is whether (2) is actually
> > correct, and *why*.
> 
> (2) is incorrect, because Common Lisp overloads number input 
> representation -- 1/2 says "exact", 0.5 says either (depending on whom 
> you listen to) "0.5 or a close approximation thereto" or "an interval 
> which contains 0.5"
> 
> This is, of course, a bad idea. The three proofs are that new users are 
> often confused by this behaviour (because it doesn't accord with the 
> notation that everyone uses in the real world),

Well, this is true of all programming languages that use floating point
numbers that are backed by a binary representation.  For computer
scientists it shows a gap in their education.  For those not formally
trained in computer science or programming it is a pitfall.

But it seems that solutions to this will not be all that pretty.  The
engineering design decision was to make the input of the numbers easy on
the user and to also make the computation fast.  Either of these design
decisions could be done differently, but it isn't clear that people
would on balance be happier with the results:

(1)  Make the numeric input be more cumbersome.  Force an explicit
notation of the type of number that you want to have and reject input
that doesn't conform to that.  Some ideas would be like:
   (double-float 0.5)
   (rational 0.5)

As a matter of fact, Common Lisp comes pretty close to providing that as
input forms, but for the convenience of users, certain abbreviations are
also allowed.  It just happens that you don't like the choice of
semantics chosen by the language designers for those abbreviations.  As
far as I can tell, when encountering a floating point number, the
semantics you want to have are something like the following:

    (defun return-number (n)
         (if (eql (rational n) (rationalize n))
             (rational n)
             n))

Now, I suppose you could modify the reader to do this for you, but it
seems like it makes things a lot more cumbersome just to handle the
relatively few cases where it would actually come into play.  In fact,
the only fractions where this would be true are the ones of the form

          m /  (2 ^ n)

and as a practical matter, I doubt that many people would choose to use
decimal inputs for values below n/4.  Now, it would perhaps be more
useful

(2)  Change the floating point representation.  Instead of using a
computationally efficient binary representation, the fractions should be
decimal fractions.  In that case, the printed representation would be
exact.  This alone would do more to "fix" people's trouble with floating
point rounding than just about any other solution.  It would have the
benefit of making the surface representation match the internals.  I
would also imagine that for most run-of-the-mill computations with
floats that the speed would even be adequate.  I'm not talking about
massive simulation runs or other heavy numeric computations.  But such
computations are much less common than, say, currency computations.

Actually, that does suggest that using $10.50 or even $3.125 would not
be the worst syntax (although perhaps US-centric) for specifying true
decimal fractions in programming languages.

For true fractions, moreover, using the rational number syntax in common
lisp actually works quite well.   Where it breaks down is with improper
fractions, which do not have the nicest representation.  Neither of the
following is particularly compact, although the former is a bit clearer:
      (+ 100 1/4)
         401/4

But if one doesn't adopt a special input syntax for decimal fractions,
it leaves open the question of how one would then specify binary
floating point numbers.  Clearly forcing the use of binary would be
impractical, and I'm not really clear about how one would introduce
something like hexadecimal notation for the fractional part of a number.

I suppose that one could adopt the convention that unmodified floating
point numbers are decimal floats and require the use of a marker like
"f", "d", "l" or "s" for binary floats.  That would leave "e" available
for scientific notation of decimal floats.

> experienced users 
> continue to argue over the approximation/interval interpretations, and 
> it causes some people post oddities suggesting that 0.5 and 1/2 aren't 
> the same number.

Well, they aren't.  One of them is of type FLOAT and the other is of
type RATIONAL.

That isn't meant as a facetious comment.  We have to distinguish between
talking about computer representations of numbers and the values of
numbers in the real world.  Although there may be a numerical equivalent
in the real world between a number designated as 0.5 and 1/2, they are
very different inside the computer.  This is a consequence of having
multiple representations for numbers in computers.

It is also why  
   (EQL 1 1.0)   => NIL
   (=   1 1.0)   => T
   (EQL 0.5 1/2) => NIL
   (= 0.5 1/2)   => NIL

There is numeric equality between any floating point numbers that happen
to have an exact representation in the binary encoding used for floats
on a particular platform.

-- 
Thomas A. Russ,  USC/Information Sciences Institute
From: ············@reillyhayes.com
Subject: Re: Type Question
Date: 
Message-ID: <1106171289.205618.250860@c13g2000cwb.googlegroups.com>
Unfortunately, this example is not entirely duplicable.  In SBCL and
Lispworks:

(EQL 1 1.0)   => T
(=   1 1.0)   => T
(EQL 0.5 1/2) => NIL
(= 0.5 1/2)   => T

The surprising one for me was (EQL 1 1.0) => T, which I think is a bug.
If we choose a rational that does not have an exact floating point
representation, the results are more illustrative:

(EQL 0.1 1/10)  => NIL
(= 0.5 1/10)    => NIL
From: Christophe Rhodes
Subject: Re: Type Question
Date: 
Message-ID: <sqzmz52im4.fsf@cam.ac.uk>
············@reillyhayes.com writes:

> Unfortunately, this example is not entirely duplicable.  In SBCL and
> Lispworks:
>
> (EQL 1 1.0)   => T
> (=   1 1.0)   => T
> (EQL 0.5 1/2) => NIL
> (= 0.5 1/2)   => T

You are either doing something very strange or doing something wrong.
If you can reproduce the first of these results in any Common Lisp
(without any user initialization) I'm sure the respective vendor would
love a bug report.

Christophe
From: ············@reillyhayes.com
Subject: Re: Type Question
Date: 
Message-ID: <1106206741.125868.122700@c13g2000cwb.googlegroups.com>
Crap.  Brain damage.  Too much time using OCAML lately.  I forgot to
include the trailing zero behind the "1.".
The point about (= 0.5 1/2) remains valid, however.

reilly
From: ·········@cern.ch
Subject: Re: Type Question
Date: 
Message-ID: <yzo8y6oy0ea.fsf@cern.ch>
googlegroups> The point about (= 0.5 1/2) remains valid, however.

I think (= 0.5 1/2) => T shows that the FP numbers are exact
representations of a subset of the rationals. Try (= 0.2 1/5) => NIL
instead.

Ole
From: ············@reillyhayes.com
Subject: Re: Type Question
Date: 
Message-ID: <1106270508.505822.323270@f14g2000cwb.googlegroups.com>
That was exactly my point, if you read my previous message.
From: Pascal Bourguignon
Subject: Re: Type Question
Date: 
Message-ID: <877jm9nmdw.fsf@thalassa.informatimago.com>
···@sevak.isi.edu (Thomas A. Russ) writes:
> That isn't meant as a facetious comment.  We have to distinguish between
> talking about computer representations of numbers and the values of
> numbers in the real world.  Although there may be a numerical equivalent
> in the real world between a number designated as 0.5 and 1/2, they are
> very different inside the computer.  This is a consequence of having
> multiple representations for numbers in computers.

But still, there is no real number in the real world.  Even when you
"compute" Pi to the 10,000,000 decimal, what you get is only a finite
number of atoms representing a rational, not a real.

If you want real numbers, you have to go to maths, ie. symbolic
computing. You can do it in Lisp, but not by typing 3.1141592 or
CL:PI, but by typing stuff like:

    (solve (x) (and (< 3 x 4) (= (sin x) 0)))
    
    (limit (p n)
           (n integer +infinity)
           (system
                (= (x 0) (square-root 2))
                (= (y 1) (expt 2 1/4))    
                (= (p 0) (+ 2 (x 0)))
                (= (x n) (/ (+ (square-root (x (1- n)))
                               (/ (square-root (x (1- n))))) 2))
                (= (y n) (/ (+ (* (y (1- n)) (square-root (x (1- n))))
                               (/ (square-root (x (1- n)))))
                            (1+ (y (1- n)))))
                (= (p n) (* (p (1- n)) (/ (1+ (x n)) (1+ (y n)))))))
    
    ;; etc.

These symbolic expressions ARE the real Pi.


-- 
__Pascal Bourguignon__                     http://www.informatimago.com/
I need a new toy.
Tail of black dog keeps good time.
Pounce! Good dog! Good dog!
From: David Steuber
Subject: Re: Type Question
Date: 
Message-ID: <87vf9ujogy.fsf@david-steuber.com>
Trent Buck <·········@tznvy.pbz> writes:

> Why does CL parse 0.5 differently to (/ 2)?  I would have expected it to
> say "Oh yes, that can be expressed exactly as a rational." and require
> the user to (more) explicitly coerce it to a float.

The short version is that the reader should not be changing the type.
0.5 is not the same type as 1/2 any more than 0 and "0" are the same.

-- 
An ideal world is left as an excercise to the reader.
   --- Paul Graham, On Lisp 8.1
From: Jeff
Subject: Re: Type Question
Date: 
Message-ID: <pan.2005.01.18.17.06.05.901674@cunningham.net>
On Mon, 17 Jan 2005 18:52:30 -0800, rhat wrote:

>...
> (seriously huge ones too, with 30+ digits). These huge ratios eat up
> all available memory, and cause a crash, so I'd like them to be handled
>...

Does anyone know why using rational numbers would cause his program to
crash? It doesn't seem to me that it would take that much more memory.
Perhaps there is another problem?

-Jeff
From: Rahul Jain
Subject: Re: Type Question
Date: 
Message-ID: <874qheavjs.fsf@nyct.net>
Jeff <·······@cunningham.net> writes:

> On Mon, 17 Jan 2005 18:52:30 -0800, rhat wrote:
>
>>...
>> (seriously huge ones too, with 30+ digits). These huge ratios eat up
>> all available memory, and cause a crash, so I'd like them to be handled
>>...
>
> Does anyone know why using rational numbers would cause his program to
> crash? It doesn't seem to me that it would take that much more memory.
> Perhaps there is another problem?

If he's actually getting numbers with 2^30 digits, it might crash. He
seems to be trying to do an arbitrarily-long search for a root to some
equation, so he'll keep getting larger denominators with each iteration,
most likely.

-- 
Rahul Jain
·····@nyct.net
Professional Software Developer, Amateur Quantum Mechanicist
From: rhat
Subject: Re: Type Question
Date: 
Message-ID: <1106142099.347468.315390@z14g2000cwz.googlegroups.com>
Yeah, you got that right: I knew something was a bit off when the
Garbage Collector kicked in ;)