在prolog中将float转换为整数

时间:2010-12-04 16:27:46

标签: floating-point integer prolog clpfd

如何在prolog中将float转换为整数?

我试过了:

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

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

2 个答案:

答案 0 :(得分:15)

您使用的谓词integer/1为true iff 其参数为整数。由于术语truncate(sqrt(9)) 不是整数,因此谓词保持,因此将失败此术语。

至少有两种方法可以获得你想要的东西:

解决方案1:快速而破碎

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

?- X is round(sqrt(9)).
X = 3.

但请注意,使用浮点数总是非常有问题。例如:

?- X is sqrt(2^10000).
ERROR: is/2: Arithmetic: evaluation error: `float_overflow'

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

解决方案2:快速通用

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

如果您需要整数平方根,请使用例如有限域约束。对于约束,只需说明持有表示正平方根的整数X

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

适用于较大的整数:

?- X*X #= 2^10000, X #>= 0.
X = 1412467032...(1496 digits omitted)

有关详细信息,请参阅

答案 1 :(得分:0)

许多Prolog系统提供了一个附加的可评估函数integer/1,与FPU指令一样,与可评估函数truncate/1相比,它返回​​一个整数而不是浮点数。

FPU语义可在两个Prolog系统中使用,例如ECLiPSe Prolog和Jekejeke 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/1在ISO核心标准中找不到。我正在测试:

?- 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不会进行截断,而是进行回合。
有人声称整数/ 1本身已被弃用。