Можно ли хотя бы приблизительно установить, какой будет максимальная потеря точности при работе с двумя значениями double
в java (сложение/вычитание)? Вероятно, наихудший сценарий — это когда два числа не могут быть представлены точно, а затем над ними выполняется операция, в результате которой получается значение, которое также не может быть точно представлено.
Java - максимальная потеря точности при одном двойном сложении/вычитании
comment
Если проблема заключается в потере точности, я бы рекомендовал использовать BigDecimal вместо double.
- person jeroen_de_schutter   schedule 20.11.2012
comment
Да, весь смысл этого вопроса в том, чтобы увидеть, насколько велика потеря. double занимает 8 байт, а BigDecimal около 40, и мне нужно хранить много точек данных
- person Bober02   schedule 20.11.2012
comment
Когда вы выполняете много операций с плавающей запятой, прирост производительности за счет использования примитивов вместо объектов может быть значительным.
- person Cephalopod   schedule 20.11.2012
Ответы (3)
person
Cephalopod
schedule
20.11.2012
Это именно то, что я хотел
- person Bober02; 20.11.2012
В худшем случае может быть потеряна все точность. Например, это может произойти, если результат больше, чем наибольшее представимое конечное число. Затем он будет сохранен как POSITIVE_INFINITY (или NEGATIVE_INFINITY).
Что касается вашего обновления, то оно может произойти с доп.
double a = Double.MAX_VALUE;
System.out.println(a);
double b = a + a;
System.out.println(b);
Результат:
1.7976931348623157E308
Infinity
Посмотреть онлайн: ideone
Как правило, размер ошибки представления зависит от размера ваших чисел.
person
Mark Byers
schedule
20.11.2012
Вы можете посмотреть на фактическую точность ваших входных данных, например, код ниже выводит:
input: 0.01000000000000000020816681711721685132943093776702880859375
range: [0.0099999999999999984734433411404097569175064563751220703125 - 0.010000000000000001942890293094023945741355419158935546875]
range size: 3.4694469519536141888238489627838134765625E-18
input: 10000000000000000
range: [9999999999999998 - 10000000000000002]
range size: 4
public static void main(String[] args) {
printRange(0.01);
printRange(10000000000000000d);
}
private static void printRange(double d) {
long dBits = Double.doubleToLongBits(d);
double dNext = Double.longBitsToDouble(dBits + 1);
double dPrevious = Double.longBitsToDouble(dBits + -1);
System.out.println("input: " + new BigDecimal(d));
System.out.println("range: [" + new BigDecimal(dPrevious) + " - " + new BigDecimal(dNext) + "]");
System.out.println("range size: " + new BigDecimal(dNext - dPrevious));
}
Вам все равно нужно будет затем оценить потери в результате вашей операции. И это не работает с крайними случаями (вокруг Infinity, NaN и т. д.).
person
assylias
schedule
20.11.2012