From: Barry Margolin on
In article <ipadnQZgrbTdF3TWnZ2dnUVZ_sWdnZ2d(a)earthlink.com>,
Raymond Toy <toy.raymond(a)gmail.com> wrote:

> On 5/11/10 9:21 AM, Captain Obvious wrote:
> > Captain>> Well, if you want to work at double accuracy, why don't
> > Captain>> you explicitly specify 2 as double-float?
> >
> > RT> Yes, I am well aware of how to get the answer I want. My question is
> > RT> what is the correct answer?
> >
> > When you're working with floating point numbers, there is no such thing
> > as "the correct answer".
>
> Get real. So, 2.0 * 3.0 should return 5.75 and that's ok? The answer
> has to be 6.0.

Every floating point number is actually a representation of a range of
numbers. So 2.0 is 2.0+/-epsilon, 3.0 is 3.0+/-epsilon, and therefore
2.0*3.0 should return 6.0+epsilon^2+/-5.0*epsilon.

What makes you think the origial 2.0 and 3.0 are exact? They came from
another compuation, that may have had roundoff error of its own. You
happen to know a priori that you typed "2.0d0", but it could just as
easily have been "2.00000000000000000987", and the fraction got lost.
If you start off with an approximation, you certainly can't expect to
get the exact answer.

--
Barry Margolin, barmar(a)alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
*** PLEASE don't copy me on replies, I'll read them in the group ***
From: Raymond Wiker on
"Captain Obvious" <udodenko(a)users.sourceforge.net> writes:

> RT> Well, the difference is way bigger than I would have expected. In
> RT> fact, I know that sbcl computes (expt 2 #c(2d0 0d0)) as (exp (* #c(2d0
> RT> 0d0) (log 2))). That (log 2) returns a single-float as expected and
> RT> required. This is what causes the loss of accuracy.
>
> Well, if you want to work at double accuracy, why don't you explicitly
> specify 2 as double-float?
>
> CL-USER> (expt 2 #c(2.0d0 0.0d0))
> #C(4.000000015237235d0 0.0d0)
> CL-USER> (expt 2.0d0 #c(2.0d0 0.0d0))
> #C(4.0d0 0.0d0)
>
> So it is not a practical issue. If you want consistent accuracy, make
> it consistent on your side.

I'm guessing that he expects the rule of floating-point
contagion to work with *all* standard Lisp numerical functions... it
makes just as much sense to treat the 10 in (log 10 10d0) as 10s0 as it
does if you tried (+ 10 10d0) (i.e, not much).



From: josephoswald+gg on
On May 11, 4:01 pm, Barry Margolin <bar...(a)alum.mit.edu> wrote:
> In article <ipadnQZgrbTdF3TWnZ2dnUVZ_sWdn...(a)earthlink.com>,
>  Raymond Toy <toy.raym...(a)gmail.com> wrote:
>
> > On 5/11/10 9:21 AM, Captain Obvious wrote:
> > > Captain>> Well, if you want to work at double accuracy, why don't
> > > Captain>> you explicitly specify 2 as double-float?
>
> > > RT> Yes, I am well aware of how to get the answer I want.  My question is
> > > RT> what is the correct answer?
>
> > > When you're working with floating point numbers, there is no such thing
> > > as "the correct answer".
>
> > Get real.  So, 2.0 * 3.0 should return 5.75 and that's ok?  The answer
> > has to be 6.0.
>
> Every floating point number is actually a representation of a range of
> numbers.  So 2.0 is 2.0+/-epsilon, 3.0 is 3.0+/-epsilon, and therefore
> 2.0*3.0 should return 6.0+epsilon^2+/-5.0*epsilon.

This is not the only way to reason about floating-point, and in fact,
is not how IEEE standardized.

The other way to think about floating point numbers is as a finite set
of exact rationals that can be represented in the format, plus a few
extras like signed zeros, infinities, denormalized numbers, and NaNs.
The union of these sets exactly corresponds to the bit patterns of the
representation. E.g., IEEE single precision has 2^32 possible members.
They don't represent intervals, they represent 2^32 different IEEE
floats, most of which are rationals.

There is a big difference between calculating a result that would fall
between two IEEE floats and choosing to return the closest
representable IEEE float and calculating with an interval and trying
to choose a representation of the resulting interval.

There is also quite a bit of difference between accepting an error of,
say, two units in the LSB vs. one unit in the LSB, and a difference of
2^29 in the LSB that you get from substituting single-precision
resolution in a double-precision representation.

From: Tamas K Papp on
On Tue, 11 May 2010 13:56:27 -0700, josephoswald+gg(a)gmail.com wrote:

> On May 11, 4:01 pm, Barry Margolin <bar...(a)alum.mit.edu> wrote:
>> In article <ipadnQZgrbTdF3TWnZ2dnUVZ_sWdn...(a)earthlink.com>,
>>  Raymond Toy <toy.raym...(a)gmail.com> wrote:
>>
>> > On 5/11/10 9:21 AM, Captain Obvious wrote:
>> > > Captain>> Well, if you want to work at double accuracy, why don't
>> > > Captain>> you explicitly specify 2 as double-float?
>>
>> > > RT> Yes, I am well aware of how to get the answer I want.  My
>> > > question is RT> what is the correct answer?
>>
>> > > When you're working with floating point numbers, there is no such
>> > > thing as "the correct answer".
>>
>> > Get real.  So, 2.0 * 3.0 should return 5.75 and that's ok?  The
>> > answer has to be 6.0.
>>
>> Every floating point number is actually a representation of a range of
>> numbers.  So 2.0 is 2.0+/-epsilon, 3.0 is 3.0+/-epsilon, and therefore
>> 2.0*3.0 should return 6.0+epsilon^2+/-5.0*epsilon.
>
> This is not the only way to reason about floating-point, and in fact, is
> not how IEEE standardized.
>
> The other way to think about floating point numbers is as a finite set
> of exact rationals that can be represented in the format, plus a few
> extras like signed zeros, infinities, denormalized numbers, and NaNs.
> The union of these sets exactly corresponds to the bit patterns of the
> representation. E.g., IEEE single precision has 2^32 possible members.
> They don't represent intervals, they represent 2^32 different IEEE
> floats, most of which are rationals.

Indeed. When one thinks about floats as intervals, operations like
(/ epsilon) lead to interesting results for small epsilons (since the
resulting interval can be quite wide, and contain a lot of rationals
which are exactly representable - which one to choose?).

I like the way the IEEE is defined - my interpretation is that it
basically says that if you take these inputs, perform a given
operation, then this is what your output should look like. This is
something that one can count on.

Tamas
From: Tim Bradshaw on
On 2010-05-11 17:47:59 +0100, Raymond Toy said:

> If FP arithmetic didn't have correct answers, you could never implement
> things such a double-double or quad-double. The fast algorithms
> critically depend on the properties of FP numbers producing exactly the
> correct rounded value.

I think the point is that "correct" is actually "predictable" or
something like that. You have to know that operations have the answers
they have, and not some other answers, but those answers might not
always be the mathematically correct ones (because they can't). It
would be good if they were always the closest possible answer to the
mathematically correct one, but I suspect that is not always the case.

And I think the problem with EXPT is that nothing really says what the
answer should be, and an implementation that does something that seems
obvious (coercing a rational to a single-float) ends up getting a
really rubbish answer.