7

如何在序言中将浮点数转换为整数?

我试过:

?- integer(truncate(sqrt(9))).
false.

?- integer(round(sqrt(9))).
false.
4

2 回答 2

16

如果它的参数是整数integer/1,则您使用的谓词为真。由于该术语不是整数,因此谓词不 成立,因此对该术语无效truncate(sqrt(9))

至少有两种方法可以得到你想要的:

解决方案1:快速而破碎

您可以使用谓词(is)/2在不同的数字表示之间进行转换。特别是,检查算术函数 round和。例如:truncateceiling

?- X 是圆形的(sqrt(9))。
X = 3。

但是,请注意,使用浮点数总是很成问题。例如:

?- X 是 sqrt(2^10000)。
错误:是/2:算术:评估错误:`float_overflow'

还有其他问题,例如舍入错误和可能的下溢。

解决方案 2:快速通用

由于浮点数的固有缺点,我强烈建议您改用更通用的机制。例如,一些 Prolog 系统支持无界精度的有理数和整数,而浮点数总是受限于机器精度。

如果您需要整数平方根,请使用例如有限域约束。有了约束,就足以说明什么适用X于表示正平方根的整数 :

?- X*X #= 9, X #>= 0。
X = 3。

适用于更大的整数:

?- X*X #= 2^10000 , X #>= 0.
 X = 1412467032...(省略 1496 位)

有关详细信息,请参阅

于 2010-12-04T16:49:51.587 回答
-1

许多 Prolog 系统提供了一个额外的可评估函数,当后者像 FPU 指令一样实现时,integer/1与可评估函数相比,它返回​​一个整数而不是浮点数。truncate/1

FPU 语义在 ECLiPSe Prolog 和 Jekejeke Prolog 等几个 Prolog 系统中可用。对于大量数字,可以看到不同的行为:

/* with float semantics */
?- X is truncate(3.0E100).
X = 3.0E100

/* with integer semantics */
?- X is integer(3.0e100).
X = 299999999999999985344178410670684
7048562051886831693752693714362110399
5064698733443536124752361947136

integer/1ISO 核心标准中没有此功能。我正在测试:

?- X is integer(3.1415).
X = 3

我可以找出以下支持:

System          Available
GNU Prolog      No
Ciao Prolog     Yes
YAP Prolog      Yes
SICStus Prolog  Yes
ECLiPSe Prolog  Yes (1)
SWI-Prolog      Yes (2)
Jekejeke Prolog Yes

(1) 如果参数不是
整数,ECLiPSe Prolog 会抛出错误。因此需要与 truncate/1 等结合使用。
另一种方法是使用 fix/1,尽管有人
声称不推荐使用 fix/1。

(2) SWI-Prolog 不进行截断,而是进行一轮。
有人声称不推荐使用 integer/1 本身。

于 2020-02-12T19:49:30.710 回答