2016-03-14 4 views
0

У меня есть серия вычислений с использованием удвоений в Java, которая всегда должна составлять до 1.0. Иногда в Java сумма немногочисленная. Я выполняю вычисления в Excel, и они составляют до 1,0. Я подозреваю, что это связано с некоторыми двойными ошибками округления. Меня озадачило то, что он работает в Excel. Любая идея, что я могу сделать, чтобы исправить это?Java double loss precision

У меня есть следующий код в Java:

double d1 = 0.979; 
    double d2 = 3; 
    double d3 = 21; 
    double d4 = d1 * d2/d3; 
    System.out.println("d4 " + d4); 

Это печатает 0.13985714285714285. В Excel, если я делаю тот же расчет (=C14*D14/E14), где C14 - d1, D14 - d2, а E14 - d3, я получаю 0.1398571428571430000. Правильно ли это Excel, потому что он округляется?

Спасибо.

+1

Арифметика с плавающей запятой имеет свои ограничения, и я подозреваю, что этот вопрос задан раньше на SO. Вы можете попробовать использовать «BigDecimal», если вам действительно нужна такая точность. –

+0

'double' в Java по своей сути является неточным. Используйте «BigDecimal» всякий раз, когда требуется точность. –

+3

Оба Java и Excel округляют для этого - математически правильный результат - бесконечное повторяющееся десятичное число. – Douglas

ответ

0

Попробуйте сделать это с помощью BigDecimals. Хотя Java double не является точным способом работы с десятичными дробями, он по-прежнему довольно точен и, конечно, более точным, чем Excel.

И с BigDecimal вы можете контролировать округление самостоятельно, а также работать с десятичными дроби, а не с двоичными дробями, что дает вам более интуитивный результат, если вы привыкли работать в десятичной системе.

public static void main(String[] args) { 
    BigDecimal d1 = new BigDecimal("0.979"); 
    BigDecimal d2 = new BigDecimal("3"); 
    BigDecimal d3 = new BigDecimal("21"); 
    BigDecimal d4 = d1.multiply(d2.divide(d3, MathContext.DECIMAL128)); 
    System.out.println("d4 " + d4); 
} 

Выходные:

d4 0.1398571428571428571428571428571428991 
+0

Почему вы говорите, что Java является «более точным чем Excel "? Excel использует математику 'double' тоже, она просто показывает слишком много десятичных знаков. – Andreas

+0

@Andreas Я имел в виду результат отображения OP из Excel, который менее точен, чем Java. –

0

Если вы хотите, чтобы округлить результат до 15 знаков после запятой вы можете сделать

double d1 = 0.979; 
double d2 = 3; 
double d3 = 21; 
double d4 = d1 * d2/d3; 
double r15 = Math.round(d4 * 1e15)/1e15; 
System.out.println("r15 " + r15); 

https://ideone.com/s0mT72 печатает

r15 0.139857142857143 

которая является числом вы попадаете первенствует.