convert float to integer in prolog

走远了吗. 提交于 2020-06-25 00:58:27

问题


How to convert float to integer in prolog?

I tried:

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

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

回答1:


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 clpfd for more information.




回答2:


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.



来源:https://stackoverflow.com/questions/4354503/convert-float-to-integer-in-prolog

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!