【问题标题】:PROLOG - How to round decimals of floating point numbers?PROLOG - 如何舍入浮点数的小数?
【发布时间】:2026-01-03 16:30:02
【问题描述】:

我在知识库中有这行:

height(Hipot,Y) :- Y is sin(pi/6)*Hipot.

它计算一个直角三角形的cathetus。

当向 Prolog 询问 Y 的值时,我得到一个不准确的数字:

?- height(1,Y).
Y = 0.49999999999999994.

但实际值是 1/2,所以它应该输出 0.5。我猜这个不准确是因为使用了pi,但我想继续使用它,所以如何将Y 舍入到0.5?

【问题讨论】:

  • @DanielLyons 我知道浮点数在编程中被“破坏”了,我只是想知道如何在 Prolog 中解决这个问题。
  • 我认为您在下面对@mat 的评论中忽略了这一点,因为您无法真正控制 Prolog 如何打印内部值。在 Python 和其他所有语言中也会发生同样的事情。您唯一可以控制的时间是当您专门将浮点数转换为字符串以进行输出(或将其传递给一些将格式化它的输出例程。)

标签: floating-point prolog prolog-toplevel


【解决方案1】:

一种直接的解决方案是使用 format/2输出具有给定“精度”的数字。例如:

?- 高度(1,Y),格式(“~2f”,[Y])0.50 Y = 0.49999999999999994。

请注意,浮点数始终会导致此类问题,我建议尽可能使用 有理数

【讨论】:

  • 我见过format/2,但我没有使用它,因为我不想输出该值,因为我正在使用它来计算必须输出的其他内容。谢谢!
【解决方案2】:

我也在努力学习序言。内置的 round 函数只去最接近的整数,所以我定义了一个规则,将它扩展到四舍五入到一定的位数:

round(X,Y,D) :- Z is X * 10^D, round(Z, ZA), Y is ZA / 10^D

我不确定它是否惯用,但它似乎有效:

?- round(5.5555, Y, 2).
Y = 5.56.

【讨论】:

  • 另一个答案,使用format/2,更惯用。
【解决方案3】:

通过使用 format/3 你可以输出到一个参数:

format(atom(A), '~2f', [Y]), writeln(A).

【讨论】: