奇怪的算术与swi-prolog [英] strange arithmetic with swi-prolog

查看:180
本文介绍了奇怪的算术与swi-prolog的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我发现结果很奇怪。为什么不是0.3?有人可以告诉我为什么这个结果?有没有可能解决这个问题。

 ? -  X是5.3-5。 
X = 0.2999999999999998。
$ b $ -

我的第二个问题是如何从'hour 'notation '13 .45'---->'15.30'换成小时数?例如,上面计算的15.30-13.45的时间将是1.85。但是我需要在一小时的时间里进行操作,而不是数字的剩余部分。像15 1/2 - 13/4,这样比较好。我尝试

 ? -  X是(5.3-5)* 100/60。 
X = 0.4999999999999997。

? - X是(5.3-5)* 100 // 60。
错误:/// 2:输入错误:`integer'expected,found`29.999999999999982'



<

解决方案

你从SWI得到的答案是正确的。

在许多编程语言,而且几乎所有的Prolog系统,浮点实现都基于二进制(radix = 2)系统。数字 5.3 不能在这个系统中精确表示,所以选择一些近似值。

 ? -  X是5.3-5-0.3。 
X = -1.6653345369377348e-16。

只要你留下的数字是2的幂(包括2 -1 ,2 -2 ,...),只要后面的浮点数的精度允许,你将得到精确的结果:

 ? -  X是5.000244140625-5-0.000244140625。 
X = 0.0。

符合Prolog标准的系统需要做的是确保在写入一个带写入选项的浮点数引用(true),浮动数据写入的方式使得它可以被精确地读取。

至于第二个问题:(//)/ 2 仅在整数上定义。如果你想将一个float转换为一个在ISO Prolog中的正常的LIA-1函数:
$ b

floor / 1,truncate / 1 ,一轮/ 1,天花板/ 1

 ? -  X是round(5.3)。 
X = 5.

但是,我宁愿推荐使用(div)/ 2 来代替(//)/ 2 。 LIA-1:2012(Standard ISO / IEC 10967-1:2012)不再支持(//)/ 2 的含义。有充分的理由。请参阅此答案了解详情。


I find the result very strange. Why not 0.3? Can somebody tell me why this result? Is it possible to fix this.

 ?- X is 5.3-5.
    X = 0.2999999999999998.

    ?- 

My second question is how would I transform from 'hour' notation '13.45' ---->'15.30' into numbers of hours ? For example the period above calculated 15.30-13.45 would be 1.85. But I need to operate on parts of the hour and not the remainders of the numbers. Like 15 1/2 - 13 /4, this way is better. I try

?- X is (5.3-5)*100/60.
X = 0.4999999999999997.

?- X is (5.3-5)*100//60.
ERROR: ///2: Type error: `integer' expected, found `29.999999999999982'

Any suggestions?

解决方案

The answer you get from SWI is correct.
In many programming languages, and practically all Prolog systems, floating point implementations are based on a binary (radix = 2) system. The number 5.3 cannot be represented precisely in this system, so some approximation is chosen. Subtracting is particularly well suited to expose such inaccuracies.

?- X is 5.3-5-0.3.
X = -1.6653345369377348e-16.

As long as you are staying with numbers that are the sum of powers of 2 (including 2-1, 2-2, ...) you will get precise results as far as the precision of the floats behind permits it:

?- X is 5.000244140625-5-0.000244140625.
X = 0.0.

What ISO conforming Prolog systems have to do is to ensure that when writing a float with write-option quoted(true), the float is written in such a manner that it can be read back precisely.

As to your second question: (//)/2 is defined on integers only. If you want to convert a float to an integer you have in ISO Prolog the usual LIA-1 functions:

floor/1, truncate/1, round/1, ceiling/1.

?- X is round(5.3).
X = 5.

However, I'd rather recommend using (div)/2 in place of (//)/2. The meaning of (//)/2 is no longer supported by LIA-1:2012 (Standard ISO/IEC 10967-1:2012) — for good reason. See this and this answer for details.

这篇关于奇怪的算术与swi-prolog的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆