5

我正在查看 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仍然会产生比1.0IEEE 64 位浮点运算正确的声音更大的值。

其他 Prolog 有什么实现?

多年后更新

更好的代码:

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 = ~20f\n",[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.
4

3 回答 3

7

SICStus 4.3.1的文档 内容如下

浮点数的范围是由 Cdouble类型提供的,通常是[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 的提议包含一些有趣的观点,但它没有考虑到William Kahan 文档的意图。特别是,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兼容的ISO/IEC 10967-1:2012取代。 IEC/IEEE 60559:2011,通用 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.0, inf.0, 0.Inf, inf,inf

分别由

SWI、YAP、Minerva、XSB、Ciao、B、GNU

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

于 2014-12-27T00:22:39.910 回答
2

您所说的 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 中,可以使用前缀 表示的 32 位浮点数0f

Jekejeke Prolog 3, Runtime Library 1.3.6
?- X is epsilon.
X = 2.220446049250313E-16
?- X is epsilon32.
X = 0f1.1920929E-7
于 2019-03-08T18:04:51.547 回答
1

Actually there is more to say about floats in Prolog. According to ISO core standard, section 7.1.3 Floating Point, different radix are allowed for internal representation.

So a Prolog system could use radix=2 or radix=10. There is only one constraint, the Prolog system should allow at least 6 digits of precision. In secton 7.1.3 Floating Point we find:

r^p-1 >= 10^6

r is the radix and p is the width of the mantissa. There are other constraints in the same section. The notions integer part and float part of a number (not to be confused with the functions)

do not refer to this section. They refer to the external decimal representation in 6.1.2 Abstract term Syntax of the ISO core standard which fixes the radix to 10.

于 2020-02-14T21:25:25.357 回答