我正在考虑编写两个有限精度的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的decimal类型的传言吗?
编辑:这不同于BigDecimal,因为它应该(a)不处理整数数组更有效,(b)它不会包装BigInteger,所以它对内存也更精简,(c)它将有一个可变的选项,所以它也会更快。总而言之,对于简单的用例,比如“我想存储一个银行余额,而没有BigDecimal的开销和double的不准确性”,减少了开销。
编辑:我打算使用int或long来做所有的数学运算,以避免经典的问题: 1586.60-708.75=877.8499999999999而不是877.85
发布于 2008-12-11 10:39:45
我强烈怀疑之所以没有做到这一点,是因为BigDecimal和BigInteger的开销并不像您想象的那样相关,并且不值得以某种微妙的方式避免它的努力和错误的风险。
举个例子:对于任何金融应用程序来说,节省几十个字节是不成问题的,而且精确度有限也是破坏交易的因素(在美国,股票价格通常有2-4位数,但如果你想与新兴市场打交道,你会遇到通货膨胀失控的货币,15位数的总和可以买到半条面包)。
基本上,这听起来就像是另一个过早优化的例子。
发布于 2010-11-24 07:03:14
大多数特别关心舍入误差的人使用BigDecimal和BigInteger,它们在大多数情况下都表现得足够好。
但是,在性能更重要的情况下,使用双精度舍入就可以了。新手通常会忘记这一点,但你不能在没有明智的回合的情况下取得双重结果,并期望得到一个明智的答案。
在绝大多数情况下,双精度和四舍五入就是你所需要的。
System.out.printf("%.2f%n", 1586.60-708.75);打印
877.85发布于 2008-12-09 20:31:19
如果你的关注点是便携设备,看看Real。Real允许将号码的precision设置为从0到16。它是为移动身份识别手机设计的。
同样有趣的是,看看constructive reals库。虽然它不是轻量级的。
参考下面的评论,你可以不使用Apache Commons Math Library来处理分数吗?有什么原因不起作用吗?
https://stackoverflow.com/questions/354045
复制相似问题