From: QCD Apprentice
Subject: Numerics question
Date: 
Message-ID: <dvvaoj$li8$1@news.doit.wisc.edu>
Hi,
So I was just playing with some things on my own time, and I 
noticed that if you have something like
(let ((zed 0))
  (dotimes (n 1000)
   (setf zed (+ 0.98 zed))
   (print zed)))
by the end I got 979.99316 instead of 980.
This was in SBCL, but CMUCL didn't really fare differently.
Now, both haskell and c++ gave me 980.
I'd just like to know if there's a reason why the common 
lisp representation seems to suffer from more error and if 
it is a potential pitfall.

From: QCD Apprentice
Subject: Re: Numerics question
Date: 
Message-ID: <dvvb46$llh$1@news.doit.wisc.edu>
QCD Apprentice wrote:
> Hi,
> So I was just playing with some things on my own time, and I noticed 
> that if you have something like
> (let ((zed 0))
>  (dotimes (n 1000)
>   (setf zed (+ 0.98 zed))
>   (print zed)))
> by the end I got 979.99316 instead of 980.
> This was in SBCL, but CMUCL didn't really fare differently.
> Now, both haskell and c++ gave me 980.
> I'd just like to know if there's a reason why the common lisp 
> representation seems to suffer from more error and if it is a potential 
> pitfall.

After thinking harder, let me rephrase my question.
Is lisp defaulting to a lower precision representation and I 
just need to tell it to use one that is higher precision?
From: QCD Apprentice
Subject: Re: Numerics question
Date: 
Message-ID: <dvvcbn$mg1$1@news.doit.wisc.edu>
QCD Apprentice wrote:
> QCD Apprentice wrote:
> 
>> Hi,
>> So I was just playing with some things on my own time, and I noticed 
>> that if you have something like
>> (let ((zed 0))
>>  (dotimes (n 1000)
>>   (setf zed (+ 0.98 zed))
>>   (print zed)))
>> by the end I got 979.99316 instead of 980.
>> This was in SBCL, but CMUCL didn't really fare differently.
>> Now, both haskell and c++ gave me 980.
>> I'd just like to know if there's a reason why the common lisp 
>> representation seems to suffer from more error and if it is a 
>> potential pitfall.
> 
> 
> After thinking harder, let me rephrase my question.
> Is lisp defaulting to a lower precision representation and I just need 
> to tell it to use one that is higher precision?

The answer is yes, sorry for wasting bandwidth and anyone's 
time.  I didn't know that it defaults to single-float 
instead of double.
From: Pascal Bourguignon
Subject: Re: Numerics question
Date: 
Message-ID: <87slp8n0ug.fsf@thalassa.informatimago.com>
QCD Apprentice <··············@gmail.com> writes:
> The answer is yes, sorry for wasting bandwidth and anyone's time.  I
> didn't know that it defaults to single-float instead of double.

But this doesn't matter (see *READ-DEFAULT-FLOAT-FORMAT*).
(note that in clisp you can also set an arbitrary precision for
LONG-FLOAT, fancy 10000 significant digit floats?)

What matters is to understand why it happens, whatever the precision
of your floating points.  Read:

"What Every Computer Scientist Should Know About Floating-Point Arithmetic"
http://docs.sun.com/source/806-3568/ncg_goldberg.html

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

What is this talk of 'release'? Klingons do not make software 'releases'.
Our software 'escapes' leaving a bloody trail of designers and quality
assurance people in it's wake.
From: Sacha
Subject: Re: Numerics question
Date: 
Message-ID: <7FGUf.333518$%z6.10394717@phobos.telenet-ops.be>
>> I'd just like to know if there's a reason why the common lisp
>> representation seems to suffer from more error and if it is a potential 
>> pitfall.

That's inherent to binary representation of decimal values.

> After thinking harder, let me rephrase my question.
> Is lisp defaulting to a lower precision representation and I just need to 
> tell it to use one that is higher precision?

(let ((zed 0))
  (dotimes (n 1000)
   (setf zed (+ 98/100 zed))
   (print zed)))

There, working with fractions gives an exact result.
That's the only way to get exact results, increasing floating point 
precision
won't help for this kind of errors, only make these harder to see.

My guess is that haskell and c++ are using double precision floats and the 
error is
hidden by the function converting these to string, but it's still there.

Sacha 
From: Alexander Schmolck
Subject: Re: Numerics question
Date: 
Message-ID: <yfsmzfgd77x.fsf@oc.ex.ac.uk>
QCD Apprentice <··············@gmail.com> writes:

> After thinking harder, let me rephrase my question.
> Is lisp defaulting to a lower precision representation and I just need to tell
> it to use one that is higher precision?

As has been pointed out, if you want exact results using rationals is the way
to go. But you're right common lisp (deplorably) uses single rather than
double floats by default. You can either write the literals expliticly as 98d0
or (setf *read-default-float-format* 'double-float). Unfortunately integers
and ratios will still be case to single-floats.

'as
From: Sacha
Subject: Re: Numerics question
Date: 
Message-ID: <oaHUf.333555$1F4.10282046@phobos.telenet-ops.be>
> double floats by default. You can either write the literals expliticly as 
> 98d0
> or (setf *read-default-float-format* 'double-float). Unfortunately 
> integers
> and ratios will still be case to single-floats.
>

CL-USER 70 > (setf *read-default-float-format* 'single-float)
SINGLE-FLOAT

CL-USER 71 > (let ((zed 0))
  (dotimes (n 1000)
   (setf zed (+ 0.98 zed)))
   zed)
980.0000000000123

CL-USER 72 > (setf *read-default-float-format* 'double-float)
DOUBLE-FLOAT

CL-USER 73 > (let ((zed 0))
  (dotimes (n 1000)
   (setf zed (+ 0.98 zed)))
   zed)
980.0000000000123

That's using lispworks ...I don't quite understand why
the same value is printed...

Sacha 
From: sross
Subject: Re: Numerics question
Date: 
Message-ID: <1143181579.430144.144770@g10g2000cwb.googlegroups.com>
All floats are of type double-float in LispWorks for Windows and
LispWorks for Linux.

http://www.lispworks.com/documentation/lw445/LWRM/html/lwref-78.htm#pgfId-959328

Cheers.
From: Pascal Bourguignon
Subject: Re: Numerics question
Date: 
Message-ID: <87k6akmz57.fsf@thalassa.informatimago.com>
"Sacha" <··@address.spam> writes:

>> double floats by default. You can either write the literals expliticly as 
>> 98d0
>> or (setf *read-default-float-format* 'double-float). Unfortunately 
>> integers
>> and ratios will still be case to single-floats.
>>
>
> CL-USER 70 > (setf *read-default-float-format* 'single-float)
> SINGLE-FLOAT
>
> CL-USER 71 > (let ((zed 0))
>   (dotimes (n 1000)
>    (setf zed (+ 0.98 zed)))
>    zed)
> 980.0000000000123
>
> CL-USER 72 > (setf *read-default-float-format* 'double-float)
> DOUBLE-FLOAT
>
> CL-USER 73 > (let ((zed 0))
>   (dotimes (n 1000)
>    (setf zed (+ 0.98 zed)))
>    zed)
> 980.0000000000123
>
> That's using lispworks ...I don't quite understand why
> the same value is printed...

The types short-float, single-float, double-float and long-float are
not necessarily distinct.
Only: 
(assert (<= (precision 'short-float)
            (precision 'single-float)
            (precision 'double-float)
            (precision 'long-float)))


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

COMPONENT EQUIVALENCY NOTICE: The subatomic particles (electrons,
protons, etc.) comprising this product are exactly the same in every
measurable respect as those used in the products of other
manufacturers, and no claim to the contrary may legitimately be
expressed or implied.