Prolog实现"float"是什么意思?



我正在查看SICStus手册的语法描述,有一个"float"的定义。但是,没有迹象表明"浮点数"的实际实现是什么。IEEE单精度还是双精度?甚至可能是BigDecimal

在SWI Prolog(或至少是SWISH)中,"浮点数"似乎是IEEE的双精度,可以通过以下方式确定:

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是最后一个值,加上1.0仍然会产生比IEEE 64位浮点运算听起来1.0更大的值。

其他Prologs有什么实现?

多年后更新

更好的代码:

efloat(C,E) :- 
   Cf is 1.0 * C, float(Cf), 
   erecur(Cf,1.0,E).
erecur(C,X,E) :- 
   Xhalf is X / 2.0, 
   Xtest is C + Xhalf, Xtest = C, !,
   format("~e/2.0 = ~20fn",[Xhalf,Xtest]),
   erecur(C,Xhalf,E).
erecur(C,X,X) :-
   Xhalf is X / 2.0, 
   Xtest is C + Xhalf,
   Xtest = C, 
   format("~e",[X]).

然后:

?- efloat(1,X). 
X = 2.220446049250313e-16.

SICStus 4.3.1 的文档如下:

浮子的范围是 C double 型提供的范围, 通常[4.9e-324, 1.8e+308](加或减)。如果溢出或 除以零,将引发评估错误异常。浮 由 64 位表示,符合 IEEE 754 标准。

与ISO一致性声明一起,这不会留下任何未决之处。请注意,"IEEE 754 标准"本身没有任何进一步的限定并不能说明太多,因为它可能意味着迷你浮点数、小数和各种模式。此外,异常处理与继续值以及其他建议使事情变得更加复杂,绝非易事。

ISO Prolog

标准要求在所有情况下生成Prolog例外(IEEE术语中的"陷阱")。没有提供 NaN、+∞ 等延续值。乍一看,这表明这些值与ISO Prolog完全不兼容。但是,子条款5.5定义了对该标准的可能扩展。特别是以下子条款允许引入延续值。

5.5.10 可评估函子

处理器可以支持一个或多个额外的可评估
函子 (9) 作为实现特定功能。
处理器可能支持 表达式的值是
附加类型的值 而不是特殊的价值。

注意 - 不使用扩展的程序
不应依赖 从评估其参数的过程中捕获错误
(如 IS/2、8.6.1),除非严格
按照 模式 (5.1 E)。

此注释揭示了背后的意图:在严格符合模式下,所有这些扩展都不存在,只有 Prolog 异常发出信号。到目前为止,扩展应该是什么样子的精确程度尚不清楚。 @jschimpf的提案包含一些有趣的观点,但它没有考虑到威廉·卡汉文件的意图。特别是,IEEE异常标志完全缺失(或相应的更好的功能),这使得NaN几乎无用。其他两个适当的代数完成不存在。(此外,该提案日期为2009年,并未考虑Cor.2:2012。

ISO

Prolog只为浮点提供一个框架(参见ISO/IEC 13211-1:1995 7.1.3浮点),二进制,十进制甚至任何正偶数基数(基数)都适合。在1980年代,一些系统(例如C-Prolog)曾经具有精度略低于单精度IEEE浮点数的浮点数。在32位中,Prolog标签和浮点数都被挤压(使用较小的尾数),而实际计算以双精度进行,旧的,不再有效,C默认值。我相信这种表示也适合 ISO。ISO Prolog至少需要6个十进制数字。但是,我不知道当前系统使用二进制IEEE双精度以外的任何东西。

ISO

Prolog中的浮点数基本上基于ISO LIA标准("语言独立算术")ISO/IEC 10967-1:1995,同时已被ISO/IEC 10967-1:2012取代,后者与ISO/IEC/IEEE 60559:2011,vulgo IEEE 754-2008兼容。

请注意,IEEE和LIA

有不同的用途:IEEE是关于浮点数的,只有几个函数,而LIA也包括更多的函数,整数算术和复数。

为了让您了解目前如何在各种Prolog系统中实现浮点运算,请考虑目标

X is 0** -1, write_canonical(X).

这应该产生一个evaluation_error(undefined).三个系统符合(IF,SICStus,Prolog IV),其他系统除了两个之外都不同。

0(+inf)Infinity.0inf.00.Infinfinf

分别由

SWI, YAP, Minerva, XSB, Ciao, B, GNU

由于所有这些输出都构成了有效的Prolog文本(有些需要中缀.),它们都是无效的扩展,因为它们重新定义了现有Prolog语法的含义。

你所说的planck_float通常被称为epsilon。许多Prolog系统都有这个值的常量,因此不需要计算。

N208 中建议的常数:

9.7.3.1 描述 epsilon 的计算结果为
从 1.0 到下一个最大浮点
数的距离 数字,实现定义的值。
https://www.complang.tuwien.ac.at/ulrich/iso-prolog/N208

许多Prolog系统支持这个常量,它可以告诉你默认浮点类型的含义。例如GNU Prolog给我:

GNU Prolog 1.4.5 (64 bits)
| ?- X is epsilon.
X = 2.2204460492503131e-016

这并不意味着Prolog系统可能只有一种浮点数据类型。Prolog系统也有可能支持多种浮点类型。例如,在Jekejeke Prolog中,可以使用由前缀0f表示的32位浮点数:

Jekejeke Prolog 3, Runtime Library 1.3.6
?- X is epsilon.
X = 2.220446049250313E-16
?- X is epsilon32.
X = 0f1.1920929E-7

实际上,关于Prolog中的浮点数还有更多要说的。根据 ISO 核心标准第 7.1.3 节浮点,内部表示允许使用不同的基数。

因此,Prolog系统可以使用基数=2或基数=10。那里只是一个约束,Prolog 系统应该允许至少 6 位精度。在第 7.1.3 节浮点中,我们发现:

r^p-1 >= 10^6

R是基数,P是尾数的宽度。那里是同一部分中的其他约束。整数部分和浮点数部分的概念(不要与函数混淆)

不要参考本节。它们指的是 6.1.2 ISO 核心标准的抽象术语语法中的外部十进制表示,该语法将基数固定为 10。

最新更新