Тригонометрические методы Java BigDecimal

Я разрабатываю математический синтаксический анализатор, который может оценивать String как '5+b*sqrt(c^2)'. Я использую ANTLR для разбора и хорошо продвигаюсь. Теперь я упал на Java-класс BigDecimal и подумал: эй, а почему бы здесь не подумать о точности.

Моя проблема в том, что Java API не предоставляет тригонометрических методов для BigDecimal, таких как java.lang.Math. Знаете ли вы, есть ли какие-нибудь хорошие математические библиотеки, такие как Apache Commons, которые решают эту проблему?

Другой вопрос - как реализовать метод мощности, чтобы я мог вычислить 4,9 ^ 1,4 с BigDecimals. Это возможно?

Также приветствуется запрос книги о численных вычислениях.


person Marco    schedule 31.01.2010    source источник
comment
Зачем для этого нужен BigDecimal? Разве не достаточно хорошо вдвое?   -  person Jonas    schedule 01.02.2010
comment
BigDecimal обычно используется для точных расчетов валюты. Вы уверены, что дубль не доставит вас туда, куда вам нужно?   -  person Nick    schedule 01.02.2010
comment
Если важна переносимость, подумайте о strictfp. (Это может немного замедлить арифметику с плавающей запятой - я никогда не тестировал тесты)   -  person Ustaman Sangat    schedule 15.12.2011


Ответы (5)


ApFloat - это библиотека, которая содержит приближения произвольной точности как тригометрических функций, так и нецелочисленных степеней; однако он использует свои собственные внутренние представления, а не BigDecimal и BigInteger. Я не использовал его раньше, поэтому не могу поручиться за его правильность или характеристики производительности, но api кажется довольно полным.

person Scott Fines    schedule 31.01.2010
comment
Только что нашел сам и убедился, что он поддерживает почти все, что мне нужно. Буду держать вас в курсе, если все работает - person Marco; 02.02.2010

BigDecimal не предоставляет эти методы, потому что BigDecimal моделирует рациональное число. Тригонометрические функции, квадратные корни и степени нецелых чисел (которые, как я полагаю, включают квадратные корни) порождают иррациональные числа.

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

person cletus    schedule 31.01.2010
comment
double также является приблизительным, но с фиксированным размером бит. BigDecimals может использовать больше бит. - person Mostowski Collapse; 15.12.2015
comment
BigDecimal является приблизительным; вот почему, если вы попытаетесь выполнить BigDecimal.ONE.divide(BigDecimal.valueOf(3)), вы получите java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result. Завершающие уравнения работают нормально, но для незавершенных вы должны указать произвольную точность. - person Ky Leggiero; 28.02.2016

Библиотека big-math предоставляет все стандартные расширенные математические функции (pow, sqrt, log, sin, ...) для BigDecimal.

https://github.com/eobermuhlner/big-math

person Eric Obermühlner    schedule 26.07.2017
comment
Эта библиотека отлично подходит для заполнения точных двойных значений, когда я устанавливаю точность до 1074 десятичных знаков, что является максимальным абсолютным значением отрицательной экспоненты для примитивного двойного значения Java. - person Al G Johnston; 25.11.2019
comment
Я не думаю, что вам нужно 1074 десятичных знака. Тип double, как определено в IEEE 754 binary64, эквивалентен MathContext.DECIMAL64 и имеет 16-значную точность мантиссы. - person Eric Obermühlner; 29.11.2019
comment
Чтобы точно вычислить двойное значение, я бы использовал MathContext.DECIMAL128 (34 цифры). Помните, что точность - это не то же самое, что цифры после десятичной точки. Под точностью в этом контексте понимается количество значащих цифр. - person Eric Obermühlner; 29.11.2019

Используя существующую функцию Java BigDecimals, а именно разрешить арифметику с ограниченной точностью, как описано здесь, я недавно реализовал sqrt / 1, exp / 1, tan / 1 и т. Д. Для этих числовых объектов.

В самих числовых алгоритмах используются серии Маклорена и Тейлора, а также соответствующие сокращения диапазона, чтобы обеспечить достаточную скорость и широту серии.

Вот пример расчета Константы Рамануджана:

Jekejeke Prolog 2, Runtime Library 1.1.8
(c) 1985-2017, XLOG Technologies GmbH, Switzerland

?- use_module(library(stream/console)).
% 0 consults and 0 unloads in 0 ms.
Yes

?- X is mp(exp(pi*sqrt(163)), 60).
X = 0d262537412640768743.999999999999250072597198185688879353856320

Эта штука написана на смеси Пролога и Явы. Работа над скоростью и точностью еще не завершена. В настоящее время исходный код кода открыт на GitHub .

person Mostowski Collapse    schedule 04.03.2017

Практически лучшей книгой по численным вычислениям будет Численные рецепты.

person Reverend Gonzo    schedule 31.01.2010
comment
Только для некоторых определений лучшего. возможно, «самый широкий», но всегда сверяйте алгоритмы с другими источниками и никогда не используйте реализации напрямую - по крайней мере, если они не обновили индексирование на основе 1 в версии C с использованием неопределенного поведения. - person Pete Kirkham; 01.02.2010