在 prolog 中将浮点数转换为整数

发布于 2024-10-06 04:58:05 字数 140 浏览 4 评论 0原文

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

我试过:

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

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

How to convert float to integer in prolog?

I tried:

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

妄断弥空 2024-10-13 04:58:05

您使用的谓词 integer/1 为真,当且仅当其参数是整数。由于术语 truncate(sqrt(9)) 不是整数,因此谓词不成立,因此失败 em> 对于这个术语。

至少有两种方法可以得到您想要的结果:

解决方案 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)

有关详细信息,请参阅

The predicate integer/1 that you used is true iff its argument is an integer. Since the term truncate(sqrt(9)) is not an integer, the predicate does not hold and therefore fails for this term.

There are at least two ways to get what you want:

Solution 1: Quick and broken

You can use the predicate (is)/2 for conversion between different number representations. In particular, check out the arithmetic functions round, truncate and ceiling. For example:

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

However, note that using floating point numbers is always highly problematic. For example:

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

There are also other issues such as rounding errors and possible underflow.

Solution 2: Quick and general

Due to the inherent shortcomings of floating point numbers, I strongly recommend you use more general mechanisms instead. For example several Prolog systems support rational numbers and integers with unbounded precision, whereas floats are always limited to machine precision.

If you need integer square roots, use for example finite domain constraints. With constraints, it suffices to state what holds for an integer X that denotes the positive square root:

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

This also works for larger integers:

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

See for more information.

这个俗人 2024-10-13 04:58:05

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

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

ISO 核心标准中没有找到此函数 integer/1。我正在测试:

?- 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 本身已被弃用。

Many Prolog systems provide an additional evaluable function integer/1, which returns an integer instead of a float compared to the evaluable function truncate/1 when the later is implemented like the FPU instruction.

The FPU semantics is available in a couple of Prolog systems like ECLiPSe Prolog and Jekejeke Prolog. The different behaviour is seen for large numbers:

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

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

This function integer/1 is not found in the ISO core standard. I was testing:

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

I could figure out the following support:

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 throws an error if argument is not
already integer. So needs to be combined with truncate/1 etc..
An alternative would be to use fix/1, although there
is a claim that fix/1 is deprecated.

(2) SWI-Prolog does not do a truncate, rather a round.
There is a claim that integer/1 itself is deprecated.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文