Библиотека высокой точности с плавающей запятой Java
Какие библиотеки для Java существуют с быстрой реализацией операций с плавающей точкой или с фиксированной точкой с точностью до нескольких тысяч цифр? Насколько они хороши?
Требование для меня заключается в том, что он реализует алгоритм умножения, который лучше алгоритма наивного умножения, который занимает в 4 раза больше времени для двукратного числа цифр (сравните Алгоритмы умножения).
Ответы
Ответ 1
На странице Arbitrary Precision Arithmetic есть три библиотеки: java.math(содержащий упомянутый BigDecimal), Apfloat и JScience. Я выполняю небольшую проверку скорости на них, которая просто использует сложение и умножение.
Результат заключается в том, что для относительно небольшого числа цифр BigDecimal в порядке (в два раза быстрее, чем остальные для 1000 цифр), но если вы используете больше цифр, это далеко - JScience примерно в 4 раза быстрее. Но явным победителем является Apfloat. Другие библиотеки, похоже, используют алгоритмы наивного умножения, которые занимают время, пропорциональное квадрату числа цифр, но время Apfloat, кажется, растет почти линейно. На 10000 цифр он был в 4 раза быстрее, чем у JScience, но на 40000 цифр он в 16 раз быстрее, чем у JScience.
С другой стороны: JScience предоставляет EXCELLENT функциональность для математических задач: матрицы, векторы, символические алгоритмы, решение систем уравнений, а что нет. Поэтому я, вероятно, займусь JScience, а позже напишу обертку, чтобы интегрировать Apfloat в алгоритмы JScience - благодаря хорошему дизайну это кажется легко возможным.
(ОБНОВЛЕНИЕ: Я написал набор тестов для пакета чисел JScience и исправил ряд ошибок. Это было в версии 4.3.1. Поэтому я могу порекомендовать его проверить.)
Ответ 2
Вы проверили производительность BigDecimal? Я не вижу ничего очевидного в JavaDoc, но это, безусловно, будет мой первый порт захода.
Ответ 3
Вы можете посмотреть в библиотеке JScience и их Real номер класса. Я не уверен, насколько производительность по сравнению с BigDecimal, но целью библиотеки является предоставление высоконастраиваемых классов для научных приложений, что кажется хорошим знаком.
Ответ 4
Apfloat предлагает высокую точность для мантиссы, но, по-видимому, дает показатель экспоненты менее чем обычную (в зависимости от того, что он падает с "Логарифмом нуля" для значений, которые могут обрабатывать double). Поэтому это не полезно для больших чисел.
Кроме того, в документации говорится:
"Ловушка существует с конструкторами Apfloat (float, long) и Apfloat (double, long). Так как поплавки и удвоения всегда представлены внутри radix 2, преобразование в любой другой радикал обычно вызывает ошибки округления и полученный апфлоат будет неточным до нужного количества цифр.
Например, 0,3 нельзя точно представить в базе 2. Когда вы создаете apfloat как новый Apfloat (0,3f, 1000), результирующее число не будет точным до 1000 цифр, но только до примерно 7 цифр (в радиусе 10). Фактически, итоговое число будет примерно как 0.30000001192092896... "
Это, по-видимому, делает Apfloat минимально полезным.
BigDecimal не имеет функции логарифма, и в документации не указано, позволяет ли она сделать большее число, чем double; показатель составляет 32 бита, что-то вроде.