passing floating point numbers through library(tcp)

John Dowding ((no email))
Mon, 22 Jul 1996 11:09:27 -0700 (PDT)

We are using library(tcp) to pass prolog terms between prolog
processess. Since I am passing goals from one process to another, I
need the (further instantiated) term to unify with the goal when it is
passed back. There is a problem when the goal contains a floating
point number. In this case, the returning goal does not unify because
the the float is not bit-identical to the one in the call.

The question is, I though that Quintus went to printing floats in
exponential notation to solve exactly this problem. Appended to this
message is a copy of a message from David Bowen from April 1991, that
makes precisely this claim.

This problems appears in version 3.2, running on Suns and SGIs.

John Dowding
dowding@ai.sri.com

Return-Path: quintus!quintus!dave@Sun.COM
Received: from drakes.ai.sri.com by Sunset.AI.SRI.COM (4.1/4.16)
id AA06175 for dowding; Tue, 2 Apr 91 11:49:52 PST
Received: from Sun.COM by drakes.ai.sri.com (4.1/4.16)
id AA13989 for dowding@ai.sri.com; Tue, 2 Apr 91 11:49:48 PST
Received: from sun.Eng.Sun.COM (sun-bb.Corp.Sun.COM) by Sun.COM (4.1/SMI-4.1)
id AA23348; Tue, 2 Apr 91 11:48:20 PST
Received: from quintus.UUCP by sun.Eng.Sun.COM (4.1/SMI-4.1)
id AA29540; Tue, 2 Apr 91 11:48:17 PST
Received: from odysseus.quintus.com by quintus.com; Tue, 2 Apr 91 11:13:57 pst
From: David Bowen <dave@quintus.com>
Date: Tue, 2 Apr 91 11:16:37 PST
Message-Id: <1311.9104021916@odysseus.quintus.com>
To: dowding@Sunset.AI.SRI.COM
Subject: Output of floating point numbers
Cc: hotline@quintus.com, ok@goanna.cs.rmit.OZ.AU

Thank you for your responses concerning my complaints about
arithmetic. I was aware that you could force floating point
numbers that correspond to integers to the integer form.
However, I still think that the decision to print all
floating-point numbers in exponent notation is a bad one.

The manual says (section G.1-1-2):

A floating point number (float) consists of a sequence of
digits with an embedded decimal point, optionally preceded by a
minus sign, and optionally followed by an exponent consisting
of upper- or lowercase 'E' and a signed base 10 integer.

This section is misleading, if it is in fact the case that the
exponent is not optional, but is always produced by Prolog.
This change certainly seems to be worth mentioning in the
manual, and in the release notes.

Both exponential form and non-exponential form are allowed in the
language. The Prolog system can use either and still be correct
according to this paragraph.

This also leads to unexpected behaviour in other predicates,
like:

| ?- number_chars(1.0, X).

X = [49,46,48,69,43,48,48]

We could consider changing this, although it might break people's
programs if they have come to rely on this behavior. I suppose we
could have a prolog_flag to allow people to have it either way.

It also disturbs me that a portray clause:

portray(Float):- number(Float), write(Float).

mostly fixes this problem. This only fixes the printing of the
floats, number_chars/2 still returns the exponent notation.
Doesn't the Prolog top-level use write?

I don't see why this disturbs you if it gets the effect that you want!
The Prolog top-level uses the equivalent of writeq, not write, to avoid
ambiguities. (Its not exactly writeq because it goes through portray
like print does.)

I know of no other programming language that will resort to
printing exponent notation as the default. Most languages only
rely on this notation when the number is either too large or
too small to print conviently otherwise. It is just plain too
hard to read.

Thanks for the comments John. I don't like this either, but let me
explain the rationale as I remember it. (Richard O'Keefe was
responsible for this decision.)

First, we want number_chars to do predictable things with floats. If
you are going to do operations on the characters corresponding to the
floating point number it may be helpful to have them in a consistent
format.

Second, we want writeq to write out floats such that no precision is
lost. That is, we want to be able to read back terms written by writeq
and get exactly the same term.

Third, it would seem valuable to have number_chars and writeq be
consistent. number_chars should also not lose any precision if you
convert a float to a char-list and back.

Fourth, we use writeq to print the results of a top-level goal. If we
didn't there could be nasty situations like distinguishing between a
variable bound to the atom 'a+b' and one bound to the term a+b.

I guess the most debatable point is the first; would it really be a
problem if number_chars attempted to use the minimal number of
characters to represent the float without loss of precision (like the
%g option in C)?

I will cc this to Richard to see if he would like to comment.