I was looking through the SICStus manual's syntax description and there is a definition of "float". However, there is no indication of what the implementation of "float" actually is. IEEE single or double precision? Maybe even a BigDecimal
?
In SWI Prolog (or at least SWISH), the "float" seems to be IEEE double precision, as can be determined via:
planck_float(P) :-
planck_float_descent(1.0,P).
planck_float_descent(X,P) :-
Xhalf is X / 2.0, Xtest is 1.0 + Xhalf, Xtest =\= 1.0, !,
write(Xhalf),writeln(Xtest),
planck_float_descent(Xhalf,P).
planck_float_descent(P,P) :-
Xhalf is P / 2.0, Xtest is 1.0 + Xhalf, Xtest == 1.0,
writeln(P).
?- planck_float(P).
P = 2.220446049250313e-16
2.22e-16
being the last value that, added to 1.0
still yields something larger than 1.0
sounds about right for IEEE 64-bit floating point arithmetic.
What implementation do other Prologs have?
The documentation of SICStus 4.3.1 reads:
Together with the declaration of ISO conformance, this does not leave anything open. Note that "the IEEE 754 standard" alone without any further qualification does not say much, as it might mean minifloats, decimals, and various modes. Also, exception handling vs continuation values and other recommendations make things much more complex and by no means easy.
The ISO Prolog standard requires to produce Prolog-exceptions ("traps" in IEEE parlance) in all cases. There is no provision of continuation values like NaN, +∞ and the like. At first cursory sight this suggests that those values are entirely incompatible to ISO Prolog. However, subclause 5.5 defines the possible extensions to the standard. There is in particular the following subclause which permits the introduction of continuation values.
This note reveals the intention behind: In strictly conforming mode all those extensions are absent and only Prolog-exceptions are signaled. How precisely an extension should look like is by far not clear. The proposal by @jschimpf contains some interesting points, but it does not take into account the intention of William Kahan's documents. In particular, IEEE-exception-flags are missing completely (or a corresponding better scoped functionality), which renders NaNs next to useless. The other two proper algebraic completions are not there. (Further, that proposal dates from 2009 and has not taken into account Cor.2:2012.)
ISO Prolog does only provide a framework for floating points (see ISO/IEC 13211-1:1995 7.1.3 Floating point), both binary, decimal and even any positive even base (radix) would fit. In the 1980s, some systems (e.g., C-Prolog) used to have floats with a precision a bit lower than single precision IEEE floats. In 32 bits both the Prolog tag and the float was squeezed (with a smaller mantissa), while actual computations were carried out in double precision, the good olde, no longer valid, C default. I believe that that representation fits into ISO, too. ISO Prolog requires at least 6 decimal digits. However, I am unaware of current systems using anything else than binary IEEE double precision.
Floats in ISO Prolog are based essentially on the ISO LIA standards ("language independent arithmetics") ISO/IEC 10967-1:1995, which in the meantime has been replaced by ISO/IEC 10967-1:2012 which is compatible with ISO/IEC/IEEE 60559:2011, vulgo IEEE 754-2008.
Note that IEEE and LIA serve different purposes: IEEE is about floats and only a few functions, whereas LIA includes more functions, integer arithmetics and complex numbers, too.
To give you an idea, how floating point operations are currently implemented in various Prolog systems, consider the goal
which should produce an
evaluation_error(undefined)
. Three systems conform (IF, SICStus, Prolog IV), and the other systems are all different except for two.is produced respectively by
As all those outputs constitute valid Prolog text (some need an infix
.
), they are all invalid extensions since they redefine the meaning of existing Prolog syntax.What you call planck_float is usually called epsilon. Many Prolog systems have a constant for this value, so that it doesn't need to be calculated.
The constant was suggested in N208:
Many Prolog systems support this constant which can tell you what the default float type means. For example GNU Prolog gives me:
This doesn't mean that a Prolog system only might have one float data type. It is also possible that a Prolog system supports multiple float types. For example in Jekejeke Prolog it is possible to use 32-bit floats denoted by the prefix
0f
: