6

我需要在 Java 中以完美的精度和固定的小数点后数来表示一些数字;在那个小数点之后,我不在乎。(更具体地说 - 金钱和百分比。)

我现在使用 Java 自己的 BigDecimal,但我发现它真的很慢并且它开始显示在我的应用程序中。

所以我想用“常规”整数和定点算术来解决它(长整数对于我的目的来说有足够大的精度)。

现在,我认为我不是第一个遇到这种问题的人,并且已经有一个库,已经实现了乘法/除法 - 但似乎不是。

现在,我很可能可以自己写(我可能会),但真的,我真的是第一个需要这个的人吗?不是已经有一些图书馆吗?

4

4 回答 4

9

decimal4j是一个 Java 库,用于基于 long 的快速固定精度算术,最多支持 18 位小数。

披露:我参与了 decimal4j 项目。

于 2015-11-06T22:00:19.750 回答
6

完全确定 BigDecimal 是性能问题吗?您是否使用分析器来找出答案?如果是,有两个可能有帮助的选择是:

1) 使用long所有值并将其乘以一个因子(例如,如果您对美分感兴趣,则为 100)。

2) 使用一个专门设计的类,该类实现类似于 的东西BigDecimal,但在long内部使用。我不知道是否存在一个好的开源库(也许是Java 数学定点库?)。很久以前(我相信是 2001 年)我自己为 J2ME 编写了一个这样的课程。做对有点棘手。请注意,除非需要高精度,否则在内部也BigDecimal使用 a ,因此在大多数情况下,此解决方案只会有一点帮助。long

由于舍入和精度问题,在许多情况下使用double不是一个好的选择。

于 2012-08-11T18:13:09.950 回答
0

尽管这不是您要问的,但这可以在不离开的情况下加速您的应用程序BigDecimal

从 Java 8 开始,这个问题BigDecimal就自行解决了。添加了一个新类MathContext并限制了计算操作的精度。

var num = new BigDecimal("1234.56780", new MathContext(10, RoundingMode.DOWN));

问题是精度10不适用于小数点后的数字。它适用于有效位数。对于1234.50,需要 6。
对于1_500_000_000.100,需要 13 来保持数字不变。
因此,当您的精度为 10 并计算数十亿捷克克朗时,精度可能会受到影响。
尽管如此,例如 1000 的精度比无限精度(我认为这是默认值)要快得多。

这也可以应用于单个操作:

BigDecimal n = new BigDecimal("0.12345");
n = n.pow(2, new MathContext(1000, RoundingMode.DOWN));
n = n.pow(2, new MathContext(1000, RoundingMode.DOWN));
n = n.pow(2, new MathContext(1000, RoundingMode.DOWN));
n = n.pow(2, new MathContext(1000, RoundingMode.DOWN));
于 2018-10-14T23:27:32.053 回答
-1

不知道为什么你需要一个图书馆。

例如,假设您要添加两个具有相同固定精度的 long

long c = a + b;

假设你有一个固定的精度数,你想乘以一个整数

long c = a * i;

假设您想将一个数字除以整数舍入为零

long c = a / i;

假设您要打印一个小数点后 3 位的固定精度数。

System.out.println(c / 1e3);

也许您过度思考问题并假设您需要一个库来处理所有问题。

如果您正在使用long或者double您可能需要少量辅助方法进行舍入,但您不需要这样的库。

于 2012-08-11T19:02:22.547 回答