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