奇怪的算术与swi-prolog [英] strange arithmetic with swi-prolog
问题描述
? - 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标准的系统需要做的是确保在写入一个带写入选项的浮点数 至于第二个问题: 但是,我宁愿推荐使用 I find the result very strange. Why not 0.3? Can somebody tell me why this result? Is it possible to fix this. 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 Any suggestions? The answer you get from SWI is correct. 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: What ISO conforming Prolog systems have to do is to ensure that when writing a float with write-option As to your second question: However, I'd rather recommend using 这篇关于奇怪的算术与swi-prolog的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!引用(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
的含义。有充分的理由。请参阅此和此答案了解详情。 ?- X is 5.3-5.
X = 0.2999999999999998.
?-
?- 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'
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.
?- X is 5.000244140625-5-0.000244140625.
X = 0.0.
quoted(true)
, the float is written in such a manner that it can be read back precisely.(//)/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.
(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.