2016-07-27 7 views
0

У меня есть матрица, заполненная двойными значениями (от 0 до 1). Для удобства давайте поговорим о строках и столбцах. Я хочу нормализовать двойные значения матрицы, так что сумма всех строк для каждого столбца возвращает 1. Эта задача вызывает проблему с плавающей точкой, поскольку, используя double, сумма никогда не вернется 1. Итак, я попытался использовать BigDecimal, но результат немного отличается.Избегайте проблем с точной точкой с использованием java.math.BigDecimal

Вот мой код:

double[][] U = new double[6][1015]; 
    double[] sumPerCol = new double[db.size()+1]; 
    for(int i=0; i<U.length; i++){ 
     for(int j =0; j<U[i].length; j++){ 
      double x = new Random().nextDouble(); 
      U[i][j] = x; 
      sumPerCol[j] += x; 
     } 
    } 
    double[] sumPerCol2 = new double[db.size()+1]; 
    for(int i=0; i<U.length; i++){ 
     for(int j =0; j<U[i].length; j++){ 
      BigDecimal x = new BigDecimal(U[i][j],MathContext.DECIMAL128); 
      BigDecimal tot = new BigDecimal(sumPerCol[j],MathContext.DECIMAL128); 
      BigDecimal x2 = x.divide(tot,MathContext.DECIMAL128); 
      U[i][j] = x2.floatValue(); 
      sumPerCol2[j] += U[i][j]; 
     } 
    } 
    for(double d : sumPerCol2){ 
     System.out.println(d); 
    } 

Конечно, я не использую BigDecimal должным образом. Может ли кто-нибудь помочь?

+0

Если вы действительно хотите точность, вы можете использовать BigDecimal, но не смешивайте их с двойными . Но даже для BigDecimal деление ** не может ** всегда давать точные результаты. –

ответ

0

Вы правы, что вы не можете безопасно использовать == для двойных значений. Но вам, вероятно, это не понадобится. Для нормализации матрицы требуется только разделить каждый элемент на сумму соответствующих элементов столбца. Если вы хотите проверить нормализацию, просто подведите итоги к элементам и проверьте, является ли разница с 1 «очень маленькой» (вы можете определить значение epsilon, скажем, 10^(- 10).

Я не вижу никаких причина для использования BigDecimal здесь. Если по какой-то причине вам действительно нужна абсолютная точность, используйте соответствующую реализацию рациональных чисел (дробей).