Java中双精度数的加法和除法



我在我的项目中使用EJML库。我写了一个方法,计算一个SimpleMatrix行向量的方差。在某些时候,我注意到,当传递一个等元素向量给这个方法时,我得到一个方差> 0.0。

我写这个是为了进一步调查,并惊讶地发现最后一行打印为false,尽管前面的打印没有产生任何输出。

// rowVec is a 1xn SimpleMatrix of equal double elements
double one = rowVec.get(0);
for (int i = 0; i < rowVec.getNumElements(); i++) {
    if (rowVec.get(i) - one != 0 || rowVec.get(i) != one) {
        System.out.println(rowVec.get(i)); // no output here
    }
}
// why false below???
System.out.println(one == (rowVec.elementSum() / rowVec.getNumElements()));
// why true below???
System.out.println(one*rowVec.getNumElements() < rowVec.elementSum());

谁能解释一下为什么等元素向量的平均值大于它的一个元素?

后续:解决我的问题:

/**
 * Calculates the variance of the argument matrix rounding atoms to the 10th
 * significant figure.
 */
public static double variance(SimpleMatrix m) {
    Preconditions.checkArgument(m != null, "Matrix argument is null.");
    Preconditions.checkArgument(m.getNumElements() != 0, "Matrix argument empty.");
    if (m.getNumElements() == 1) return 0;
    double mean = m.elementSum() / m.getNumElements();
    double sqDiviations = 0;
    for (int i = 0; i < m.getNumElements(); i++) {
        sqDiviations += Math.pow(decimalRoundTo(mean - m.get(i), 10), 2);
    }
    return sqDiviations / m.getNumElements();
}
/** Rounds a double to the specified number of significant figures. */
public static double decimalRoundTo(double d, int significantFigures) {
    double correctionTerm = Math.pow(10, significantFigures);
    return Math.round(d * correctionTerm) / correctionTerm;
}

浮点运算不精确。当你把ndouble加起来,然后把结果除以n时,你并不总是得到你开始的数字。

例如:

double x = 0.1;
double y = x + x + x;
System.out.println(y / 3. - x);

打印

1.3877787807814457E-17

我强烈推荐《What Every Computer Scientist Should Know About浮点算术》

最新更新