繁体   English   中英

轻量级Java十进制类

[英]Lightweight Java Decimal Class

我正在考虑为BigDecimal写两个有限精度的替代品,即DecimalInt和DecimalLong。 这些将能够处理int和long的实际边界内的数字以及任意数量的小数位,可以以可变形式和不可变形式创建。 我的计划是使DecimalInt支持+/- 999,999,999到+/- 0.999999999和DecimalLong相同,但最多18位数。

这可以通过将DecimalInt的十进制数字计数值保持为0-9,将DecimalLong的十进制数字计数值保持为0-18以及存储为缩放的int或long的实际值来完成。 正常使用的是小数字小数,例如金钱和股票价格,通常为2-4位小数。

基本要求是(a)精益足迹(2个类,加上OverflowException),以及(b)完全支持所有基本操作以及所有有意义的数学。

谷歌搜索结果没有返回任何明显的命中 - 它们似乎都属于任意小数。

我的问题是:这已经完成了吗? 这有隐藏的微妙之处,这就是为什么它还没有完成? 有没有人听说过Java支持像DotNet这样的十进制类型的传言。

编辑:这与BigDecimal不同,因为它应该是(a)不处理一组int的更高效的地狱,并且(b)它不会包装BigInteger所以它也会在内存上更精简,并且(c)它有一个可变选项,所以它也会更快。 总而言之 - 对于简单的用例,例如“我想存储银行余额而没有BigDecimal的开销和双精度的不准确性”,开销更少。

编辑:我打算用int或long做所有的数学运算来避免经典问题:1586.60-708.75 = 877.8499999999999而不是877.85

我强烈怀疑为什么没有这样做的原因是BigDecimal和BigInteger的开销并不像你想象的那么重要,并且避免它不值得努力以及以某种微妙的方式弄错它的风险。

使用你的例子:对于任何金融应用程序,节省几十个字节是一个非问题和有限的精度是一个交易破坏者(股票价格我通常在美国2-4位数,但如果你想与新兴市场打交道,你会遇到通货膨胀失控的货币,15位数的货币会给你买半条面包。

基本上,这听起来只是另一种过早优化的情况。

大多数特别关注舍入错误的人使用BigDecimal和BigInteger,它在大多数情况下表现都很好。

但是,在性能更为关键的情况下,使用double with rounding可以完成工作。 新手经常会忘记这一点,但是如果没有明智的回合,你不能只取一个双重结果,并期望获得一个明智的答案。

在绝大多数情况下,只需要四舍五入就可以了。

System.out.printf("%.2f%n", 1586.60-708.75);

版画

877.85

如果您专注于便携式设备,请查看Real Real允许将数字的精度设置为0到16.它专为MIDP手机设计。

同样有趣的是,看看建设性的实力库。 虽然它不是轻量级的。

在参考下面的评论时,您是否可以使用Apache Commons Math Library来处理分数? 有什么理由不起作用吗?

如果你正在寻找一个固定的,少量的小数位来处理钱,那么这通常是通过保持整数(如果必要的话很长)的分数或百分之一分来完成的。

如果你正在处理金钱,那么你需要小心如何处理四舍五入。 如果要对您的计算进行审计,那么有关于如何完成此类事情的规则。 另外我假设你知道某些操作不能精确完成(除法就是明显的例子)。

在我看来,如果你想要任意精度,那么你将需要一个未定义的位数来表示尾数。 这意味着尾数需要某种数组分配策略。 你可以在这里制作自己的,但BigInteger相当有效地完成它,它的工作原理

您需要指定需要表示的最小(非零)值。 这将是10 ^ - (2 ^ n),其中n + 1是您分配给指数的位数。 使用BigDecimal,这是10 ^ - (2 ^ 31)。 您可以使用任意大小的指数,但该范围对任何人都应该足够。

所以你需要的是一个无界的整数尾数来给你任意精度和一个固定大小的指数,这取决于你想要的最小可表示值。 基本上这是BigDecimal; 唯一的变化是你将使用一些较小的对象而不是BigDecimal使用的int。 我怀疑节省空间是否值得。 我认为BigDecimal将以你自己制作的任何解决方案为基础,几乎不会占用你所需要的内存。

当然,您可以选择您需要的最大有效数字; 然后你需要固定大小的存储空间用于尾数和指数,这是一个更少的存储空间。 只需使用固定数量的长尾作为尾数。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM