double x = 1;
double y = 3 * (1.0 / 3);
x == y
在我正在研究的一个powerpoint中,它表示该声明在逻辑上是有问题的。我不知道为什么它是这样的,我的意思是你使用==原语是正确的,还是逻辑上有问题,因为双打没有完全存储或者我错过了一些明显的东西?感谢
答案 0 :(得分:5)
我认为你已经得到了它:由于数据类型是双精度数,而不是int或Integer,因此得到的x和y可能不完全相等。
答案 1 :(得分:3)
这在逻辑上是有问题的,因为最后的compare语句将评估为false。双打存储为一系列2的幂。因此,像1/2和1/4和1/8这样的值实际上可以用浮点格式表示,但不是1/3。它将近似为1/4 + 1/64 + ......现在它可以完全适用于1/3
比较浮点数的正确方法是这样的:
Math.double.abs ( x - y ) > tol
其中tol设置为足够小的东西,具体取决于您的应用程序。例如,大多数图形应用程序在tol = 0.00001
时运行良好答案 2 :(得分:2)
由于1.0 / 3
为0.3333...
,因此最高为double
的容量。 3 * 0.3333...
为0.9999...
,最高为双倍容量。
所以我们有问题1 == 0.9999...
,我猜你可以称之为“逻辑上有问题”。
答案 3 :(得分:1)
这是因为舍入错误。这个问题类似于处理无法用您正在使用的格式精确表达的数字时的小数精度问题。
例如,对于十进制精度的六位数,1/3的最佳值是.333333
。但是:
1/3 + 1/3 + 1/3
- > .33333 + .333333 + .33333 = .999999 != 1.000000
哎哟。对于2/3,您可以使用.666666
或.666667
,但不管怎样,您都遇到了问题。
如果2/3 - > .666666
然后:
2/3 + 1/3
- > .333333 + .666666 != 1.000000
哎哟。
如果是2/3。 - > .666667
然后:
1/3 * 2 - 2/3
- > .333333 * 2.00000 - .666667 = .666666 - .666667 != 0
哎哟。
它类似于双打。 This paper被认为是关于该主题的权威性工作。简单来说 - 永远不要将浮点数比较为相等,除非你确切知道你在做什么。
答案 4 :(得分:0)
逻辑上有问题,因为双打未完全存储
或多或少。
作为一般规则,double
不能代表实数的精确值。值1/3
就是一个例子。
某些数字可以精确表示为double
值。 1.0
和3.0
就是例子。但是,除法运算符会生成一个无法表示的数字(在这种情况下)。
一般情况下,使用==
来比较double
或float
值的任何代码都值得怀疑......因为您需要仔细分析每个案例才能知道是否使用==
是正确的。 (对于那些在很小的时候就在10年级做算术的人而言,分析并不直观!)
从软件工程的角度来看,您需要对==
用法进行逐案分析的事实使得这一做法值得怀疑。良好的软件工程(部分)是关于消除错误和错误来源。