Prev Next Up Home Keys Figs Search New

Prolog and IEEE floats

Appeared in Volume 7/2, May 1994

Keywords: floats.


joachim@ecrc.de
Joachim Schimpf
6th December 1993 
Here are a some points about Prolog and floating point numbers that different Prologs handle differently and which should probably be addressed in the forthcoming ISO standard:

Should e.g.

	X is 1/0.

raise an error or return infinity? (ECLiPSe does the former, SICStus the latter)

In the latter case, what is the syntax for the infinity value? I.e what should

	X is 1/0, writeq(X).

print? Keep in mind that writeq/1 is supposed to print every Prolog term such that it can be read back using read/1. (SICStus prints inf, which is read back as an atom and thus wrong)

Is the infinity value a number or not, i.e. does

	X is 1/0, number(X).

succeed or fail?

Same questions for IEEE NaNs, e.g. the result of X is sqrt(-2).

In IEEE arithmetic there are positive and negative zeros. Is Prolog allowed to show this difference to the user? For example, the following fails with SICStus and also with old versions of ECLiPSe:

	0.0 is 0.0 * -1.0.  

(the multiplication yields -0.0 which doesn't unify with 0.0)

Any opinions?


mcovingt@aisun3.ai.uga.edu
Michael Covington
6th December 1993  
As I understand it, the draft Prolog standard picks up a different ISO standard for computer arithmetic, specifying lots of such things in detail. The standardizers felt that computer arithmetic should not be language-specific.


joachim@ecrc.de
Joachim Schimpf
7th December 1993   
I realize that. But my posting was exactly about some problems that are not addressed by any arithmetic standard because they are specific to Prolog (and probably other symbolic languages).


ted@crl.nmsu.edu
Ted Dunning
7th December 1993   
Joachim Schimpf writes:

(the multiplication yields -0.0 which doesn't unify with 0.0)

In Prolog, unification is essentially useless for floats other than to assign values to previously unbound variables. The classic cause is the fact that you can have A = B, B = C, and A != C if you allow anything but strict bit equality. If you enforce strict bit equality for unification, then other things break.


jtai@yallara.cs.rmit.OZ.AU
Chen Hiung Tai
9th December 1993   
Joachim Schimpf writes:

Should e.g.

	X is 1/0.

raise an error or return infinity?

Interesting point. In CLP system like CLP(R), this is handled by

 A = B/C % assume { A,B,C } = number

rewriten to:

 A * C = B

therefore

 C = 0 then B = 0 & A = don't care

so

 C = 0 & B != 0 then FAIL

I'm quite sure this is done in CLP(R) so at least there is one good reason (compatability) to do it this way. Unfortunately, complications arise when the equality is not ground. So, this method is not perfect.


ok@goanna.cs.rmit.oz.au
Richard A. O'Keefe
9th December 1993   
Joachim Schimpf writes:

Should e.g.

	X is 1/0.

raise an error or return infinity?

The IEEE 754 standard is perfectly clear on this point. It *requires* as the default behaviour that 1.0/0.0 return +Infinity. It *recommends* in a non-normative appendix that there be some means by which a programmer can get an Overflow exception instead, If that person *explicitly* asks for it. Any system in which 1.0/0.0 *by default* raises an exception thereby fails to conform to IEEE 754.

When I was at Quintus, we found UNIX systems whose vendors claimed that they conformed to 754 but failed to provide any means at all for producing infinities. We also found UNIX systems which did conform to 754 but where the "please give me an exception" functions did not exist or had no effect. Of course there are systems which don't claim to follow 754 at all (IBM mainframes, Crays, ...) and there it may be burdensome to emulate infinities.

The standard should not require conformance to IEEE 754.

The standard should not forbid conformance to IEEE 754 either.

Note that there are other things too. What about underflow? Should that return 0, or produce an exception? If you like exceptions, how about the IEEE 754 "Inexact" exception?

I suggest that the standard should define the exceptions that may be raised, and simply state that the actual behaviour is implementation defined, either an implementation will raise the exception or it will yield some result instead and it must document which result. It can also require an environment enquiry (I wrote a detailed paper on floating point arithmetic for Prolog, it's available from the University of Auckland) such as:

	environment(floating_point_arithmetic(ieee(754))) 

so that a program can tell in advance what it's likely to get.

Joachim Schimpf continues:

In the latter case, what is the syntax for the infinity value? I.e what should

	X is 1/0, writeq(X).

print? Keep in mind that writeq is supposed to print every Prolog term such that it can be read back using read/1.

One wants a form which would not have been syntactically legal as anything else. Something like

+1.0Infinity	+{bits}QNaN
-1.0Infinity	-{bits}SNaN

would do fine. That is, something which looks like a floating point literal, but instead of a scaling factor beginning with "e" there is a block of several letters saying what kind of special value it is. (Note that there are lots of Quiet Not-a-Numbers and lots of Signalling ones, so the form for QNaNs and SNaNs needs the numeric part to say which one you got.)

Joachim Schimpf:

Is the infinity value a number or not, i.e. does

	X is 1/0, number(X).

succeed or fail?

It is a member of the algebra whose axioms are given by IEEE 754. It is a member in perfectly good standing. One of the reasons for having the thing in the first place is to make the floating-point algebra CLOSED. Treating infinities or NaNs as anything but numbers would miss the whole point.

Joachim Schimpf:

Same questions for IEEE NaNs, e.g. the result of X is sqrt(-2).

See above.

Joachim Schimpf:

In IEEE arithmetic there are positive and negative zeros. Is Prolog allowed to show this difference to the user? E.g. the following fails with SICStus and also with old versions of ECLiPSe:

	0.0 is 0.0 * -1.0.  

(the multiplication yields -0.0 which doesn't unify with 0.0)

If you DON'T make this difference visible to the user, it isn't IEEE 754 arithmetic. The distinction between zeros is not an optional feature. Note that

(+1.0)/(+0.0) => +1.0Infinity
(+1.0)/(-0.0) => -1.0Infinity

This can be justified if you regard "0" as really standing for "epsilon" and Infinity as really standing for 1/epsilon.

It is quite clear from the IEEE standard that if

	X is +0.0, Y is -0.0

then

	X \== Y, \+ (X = Y)

but it is equally clear that

	X =:= Y, \+ (X =\= Y).

If you do anything different, it isn't 754-conformant.

Prev Next Up Home Keys Figs Search New