2016-08-23 104 views
0

我看到一个问题,并不太明白。倍增变量

第一我们创建任意值:

int x = random(); 
int y = random(); 
int z = random(); 

(int是32位) 然后继续:

double dx = (double) x; 
double dy = (double) y; 
double dz = (double) z; 

(双为64位)

问题是告诉如果下一个陈述是总是是真(返回1)或不。

a. dx+dy+dz==dz+dy+dx 

b. dx*dy*dz==dz*dy*dx 

答案(一)说:“是,在由双的范围内精确表示的” (是这样,它还是不总是真的吗?如果是不总是真实, (b)的答案是“否,例如dx = Tmax,dy = Tmax-1,dz = Tmax-2” (dx,dy,dz,返回0的3个值的示例)

我试过了,结果是相同的结果(但很有可能我错了: - /)

我想了解为什么那些答案是正确的

谢谢!

回答

1

在浮点运算中,您应该从不测试是否相等。一个典型的例子是0.1 + 0.2 != 0.3。 (有关更多信息,请参阅http://0.30000000000000004.com/以了解更多信息,特别是查看您的语言是否隐藏了此内容。它很好地解释了这种情况,因为0.1和0.3不能用双精度表示。)应该检查浮点值看看它们是否在一定范围内足够接近,通常称为“宽容”。

见IEEE 754的定义:https://en.wikipedia.org/wiki/Double-precision_floating-point_format

我的答案不同意(A),因为它是毫无意义的,指定什么可以“精确表示”由双 - 如果每个输入的双重表示给定随机位(x,y,z),那么根据定义,它就是精确的表示。另外,可以说“是的,但只在某些条件下”作为答案“是否这个总是是真的?”在这种情况下的答案是“否”。 (a)的一个反例如下。我通过考虑浮点数只具有一定的相对精度来构造这一点,因此将非常小的数添加到非常大的数可能没有区别。让这个小号码足够大,它会。

  • 1e16 + 1 + 1 = 10000000000000000
  • 1 + 1 + 1e16 = 10000000000000002

作为(b)中,我试图随机的第一件事情是一个反:

  • 0.1 * 0.1 * 0.7 = 0.007000000000000001
  • 0.7 * 0.1 * 0.1 = 0.006999999999999999