Операция заказа для максимизации двойной точности

Я работаю над некоторым инструментом, который вычисляет числа, которые могут приблизиться к 1e-25 в худших случаях и сравнивать их вместе, на Java. Я, очевидно, использую двойную точность.

Я прочитал в еще один ответ, который я не должен ожидать больше, чем 1e-15 до 1e-17, и этот другой вопрос касается повышения точности при упорядочивании операций в "лучшем" порядке.

Какие операции с двойной точностью более склонны к снижению точности на этом пути? Должен ли я попытаться работать с номером как можно большим или малым? Делать деления сначала перед умножением?

Я бы предпочел не использовать классы BigDecimal или эквивалент, так как код уже достаточно медленный;) (если только они не Конечно, скорость удара слишком велика).

Любая информация будет принята с благодарностью!

EDIT. Тот факт, что числа являются "маленькими" по абсолютной величине (1е-25), не имеет значения, так как двойной может спуститься до 1е-324. Но важно то, что, когда они очень похожи (оба в 1е-25), мне приходится сравнивать, скажем, 4.64563824048517606458e-21 - 4.64563824048517606472e-21 (разница 19 и 20 цифр). Когда вычисляет эти числа, разница настолько мала, что я могу ударить по "ошибке округления", где остаток заполняется случайными числами.

Возникает вопрос: "как упорядочить вычисления так, чтобы эта потеря точности была минимизирована?". Это может быть деление перед умножением или добавлением в первую очередь.

Ответы

Ответ 1

Благодаря @John за то, что вы указали очень полную статью о арифметике с плавающей запятой.

Оказывается, что, когда требуется точность, операции должны быть переупорядочены, а формулы адаптированы для предотвращения потери точности, как описано в Отмена: при сравнении чисел, которые очень близки друг к другу (это мой случай), может произойти "катастрофическое аннулирование", что приводит к огромной потере точности. Часто повторная запись формулы или операции переупорядочения в соответствии с вашими априорными знаниями значений операндов могут привести к достижению большей точности в исчислении.

Что я буду помнить из этой статьи:

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

В последнем случае помните, что вычисление (x - y) * (x + y) дает более точные результаты, чем x * x - y * y.

Ответ 2

Если важно получить правильный ответ, вы должны использовать BigDecimal. Он медленнее, чем двойной, но в большинстве случаев он достаточно быстр. Я не могу придумать много случаев, когда вы делаете много вычислений с такими маленькими числами, где не имеет значения, правильный ответ - по крайней мере, с Java.

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