Java BigDecimal三角函数方法

13
我正在开发一个数学解析器,能够评估类似于 '5+b*sqrt(c^2)' 的字符串。我正在使用 ANTLR 进行解析,并取得了良好的进展。现在,我发现 Java 类 BigDecimal,并想:嗨,为什么不考虑精度呢。
我的问题是 Java API 没有提供 java.lang.Math 中的三角函数方法,如 BigDecimal。您知道是否有任何像 Apache Commons 这样的优秀数学库可以解决这个问题吗?
另一个问题是如何实现幂次方运算,以便我可以使用 BigDecimal 计算 4.9 ^ 1.4。这可行吗?
关于数值计算的书籍推荐也会很受欢迎。

为什么你需要BigDecimal呢?double不够好吗? - Jonas
BigDecimal通常用于精确的货币计算。你确定double不能满足你的需求吗? - Nick
如果可移植性很重要的话,那么请考虑使用strictfp。(虽然可能会稍微减慢浮点运算速度 - 我从未真正进行基准测试。) - Ustaman Sangat
5个回答

7
BigDecimal没有提供这些方法,因为BigDecimal模拟了一个有理数。三角函数、平方根和非整数幂(我猜包括平方根)都生成无理数。

可以用任意精度的数字来近似这些值,但确切的值不能存储在BigDecimal中。这不是它们的真正用途。如果你只是近似某些东西,那么最好使用double


6
双精度浮点数也可以近似,但位数是固定的。BigDecimal 可以使用更多的位数。 - user502187
BigDecimal 是近似值;这就是为什么如果你尝试执行 BigDecimal.ONE.divide(BigDecimal.valueOf(3)),你会得到一个 java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result. 终止方程可以正常工作,但对于非终止方程,您必须指定任意精度。 - Ky -
无论以什么方式存储浮点数都会是一个近似值。对于无理数来说,精确值无法以任何格式进行存储。 - MiguelMunoz

7

ApFloat 是一个库,其中包含了三角函数和非整数幂的任意精度逼近计算;但是,它使用自己的内部表示方式,而不是 BigDecimalBigInteger。我以前没有使用过它,所以无法保证其正确性或性能特征,但是 API 看起来相当完整。


刚刚自己找到了,发现它支持我需要的几乎所有功能。如果一切正常,我会及时通知你。 - Marco

4

这个库非常适合用于填充准确的双精度值,当我将精度设置为1074位小数时,它可以达到Java原始双精度值负指数的最大绝对值。 - Al G Johnston
我认为你不需要1074个小数位。在IEEE 754二进制64中定义的double类型等同于MathContext.DECIMAL64,并且具有16位数字精度。 - Eric Obermühlner
为了准确计算双精度值,我会使用MathContext.DECIMAL128(34位数字)。请记住,精度与小数点后的数字不是同一概念。在这个上下文中,精度指的是有效数字的数量。 - Eric Obermühlner

0

只有在某些定义上才能称之为“最好”。可能是“最广泛的”,但始终要根据其他来源检查算法,并且永远不要直接使用实现 - 至少如果它们没有使用未定义行为更新C版本中的基于1的索引。 - Pete Kirkham

0

利用 Java BigDecimals 的一项现有功能——允许有限精度算术(如此处所述),我最近为这些数字对象实现了 sqrt/1、exp/1、tan/1 等。

这些数值算法本身使用 Maclaurin 和 Taylor 级数,以及适当的范围缩减来确保足够的速度和级数广度。

以下是一个计算示例:拉马努金常数:

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

这个东西是用Prolog和Java混合编写的。它的速度和准确性仍在不断改进中。该代码目前在GitHub上开源。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接