[comp.lang.prolog] Fun With Floats in Quintus

eiverson@nmsu.edu (Eric Iverson) (08/14/90)

How oh how does one represent the numbers 8.1 and 5.4 in Quintus
Prolog?  I have tried everything I can think of without any luck.
Below are a few of my attempts:
----------------------------------------------------------------------------
Quintus Prolog Release 2.5.1 (Sun-4, SunOS 4.1)

| ?- X is 8.1.

X = 8.09999

| ?- X is 5.4.

X = 5.39999 

| ?- number_chars(8.1,X),number_chars(Y,X).

X = [56,46,48,57,57,57,57],
Y = 8.09998 

| ?- number_chars(5.4,X),number_chars(Y,X).

X = [53,46,51,57,57,57,57],
Y = 5.39999 

| ?- X is 8.1+0.00001.

X = 8.09999 

| ?- X is 8.1+0.00002.

X = 8.10001 

| ?- X is 8.09999+0.00001.

X = 8.09998

| ?- X is 8.09999+0.00002.

X = 8.09999 

| ?- X is 8.09999+0.00003.

X = 8.09999 

| ?- X is 8.09999+0.00004.

X = 8.10001 

--
------------------------------------------------------------------------
Eric Iverson				Internet: eiverson@nmsu.edu
Computing Research Lab
Box 30001/3CRL				Life is something to do when
New Mexico State University		you can't get to sleep.
Las Cruces, NM 88003-0001			-Fran Lebowitz
(505) 646-5711

vu0310@bingvaxu.cc.binghamton.edu (R. Kym Horsell) (08/14/90)

In article <EIVERSON.90Aug13174424@aigyptos.nmsu.edu> eiverson@nmsu.edu (Eric Iverson) writes:
>
>How oh how does one represent the numbers 8.1 and 5.4 in Quintus
>Prolog?  I have tried everything I can think of without any luck.

There are some real numbers which can't be represented in floating
point. The language (nor implementation) is not at fault. 
For example, try to write down the representation of 0.1 (decimal) in binary.

-Kym Horsell

ok@goanna.cs.rmit.oz.au (Richard A. O'Keefe) (08/14/90)

Seemingly, there are comp.lang.prolog articles not making it to Oz.
I missed this one:

> In article <EIVERSON.90Aug13174424@aigyptos.nmsu.edu> eiverson@nmsu.edu (Eric Iverson) writes:
> >How oh how does one represent the numbers 8.1 and 5.4 in Quintus
> >Prolog?  I have tried everything I can think of without any luck.

But this one got through:

In article <3829@bingvaxu.cc.binghamton.edu>, vu0310@bingvaxu.cc.binghamton.edu (R. Kym Horsell) writes:
> There are some real numbers which can't be represented in floating
> point. The language (nor implementation) is not at fault. 
> For example, try to write down the representation of 0.1 (decimal) in binary.

That's perfectly correct.  Old versions of Quintus Prolog used a "short"
floating-point format, which exacerbates the problem, but the problem does
exist in any floating-point system.

However, Quintus Prolog comes with a library package library(long)
which implements arbitrary precision rational arithmetic, so there
IS a way to represent 8.1 and 5.4 exactly:

	?- ensure_loaded(library(long)).

	?- eval(X is 81/10), eval(Y is 54/10).
	X = 81/10
	Y = 27/5

I have been telling Quintus for years that bignums and rationals should
be in all the versions of QP, not just Xerox Quintus Prolog, but Quintus
were much more interested in meeting the needs expressed by their paying
customers before adding "neat" features that customers weren't asking for.
library(long) isn't as nice as having these things built in, but it does
the job.  I'm still looking after the Quintus Prolog library, and if you
have any problems with library(long), please tell me.

-- 
The taxonomy of Pleistocene equids is in a state of confusion.

eggert@twinsun.com (Paul Eggert) (08/14/90)

R. Kym Horsell writes:

	There are some real numbers which can't be represented in floating
	point. The language (nor implementation) is not at fault.  For example,
	try to write down the representation of 0.1 (decimal) in binary.

This cliche doesn't apply to Iverson's problem.  Free-format output should
print no more digits than are needed to communicate the value.  For example,
with IEEE double precision floating point, the closest representable number to
8.1 is X = 8.0999999999999996447286321199499070644378662109375.  But when I
print X in free format, I should see just "8.1", because it's much shorter
and communicates X equally well.  For more on this subject, see:

	William D Clinger
	How to Read Floating Point Numbers Accurately
	Sigplan notices 25, 6 (June 1990), 92-101.

	Guy L. Steele Jr. and Jon L White
	How to Print Floating-Point Numbers Accurately
	Sigplan notices 25, 6 (June 1990), 112-126.

Perhaps Quintus's problem is that they've stolen some low order bits of the
fraction for Prolog tag bits, but their I/O routines are the same as C's and
are thus programmed as if the low order bits were significant.

vu0310@bingvaxu.cc.binghamton.edu (R. Kym Horsell) (08/14/90)

In article <1990Aug14.034632.5561@twinsun.com> eggert@twinsun.com (Paul Eggert) writes:
[stuff deleted]
>Perhaps Quintus's problem is that they've stolen some low order bits of the
>fraction for Prolog tag bits, but their I/O routines are the same as C's and
>are thus programmed as if the low order bits were significant.

Yep, representation thy has a few wrinkles. Thanks for the references;
I'll follow them up.

I don't think Quintus uses tag bits in its representation of
floats (at the expense of mantissa). From the C routines I use 
(under Ultix) it seems the low order 4 or 5 bits would have to be used 
to account for the discrepancy observed by Iverson -- too much surely
(there aren't that many primitive types in QP for one thing).

R O'K may be able to correct me if I've applied S Holmes incorrectly
here.

-Kym Horsell

vu0310@bingvaxu.cc.binghamton.edu (R. Kym Horsell) (08/15/90)

In article <1990Aug14.034632.5561@twinsun.com> eggert@twinsun.com (Paul Eggert) writes:
>with IEEE double precision floating point, the closest representable number to
>8.1 is X = 8.0999999999999996447286321199499070644378662109375.  But when I

While my sun and sparc came up with the same rep as you(rs),
I don't think it is the *closest* one to 8.1 in 55 bits of mantissa.

Since 8.1 is hex 81[9's]8 where the lsb of "8" is the 56th bit,
it rounds up (since the next bits after the 55th are 1100) to
81[9's]a which gives:

8.100000000000000088817841970012523233890533447265625

[I became sus when my vax gave 8.1[0's]1 for a double 8.1].

Maybe a few C printf's need overhaul, besides the point of rounding
to the nearest number in significant decimal digits.

-Kym Horsell

upl@gumby.cs.wisc.edu (Undergrad Projects Lab) (08/15/90)

In article <3829@bingvaxu.cc.binghamton.edu> vu0310@bingvaxu.cc.binghamton.edu.cc.binghamton.edu (R. Kym Horsell) writes:
>In article <EIVERSON.90Aug13174424@aigyptos.nmsu.edu> eiverson@nmsu.edu (Eric Iverson) writes:
>>
>>How oh how does one represent the numbers 8.1 and 5.4 in Quintus
>>Prolog?  I have tried everything I can think of without any luck.
>
>There are some real numbers which can't be represented in floating
>point. The language (nor implementation) is not at fault. 
>For example, try to write down the representation of 0.1 (decimal) in binary.
>
>-Kym Horsell

This is a common canard in many language implementations.  The latest Scheme
(R**4) has fixed this.

See the 1990 ACM Conference on Program Language Design and Implementation
for papers by Guy L. Steele and William Clinger on how to correctly implement

--
Doug Quale
picard@cs.wisc.edu