我的Java程序以高精度的计算为中心,这需要精确到至少120位小数点。
因此,程序中的所有非整数数字都将由BigDecimals表示.
显然,我需要为BigDecimals指定舍入的准确性,以避免无限的十进制表达式等等。
目前,我发现必须在BigDecimal的每一次实例化或数学运算中指定精确性是一个巨大的麻烦。
有没有办法为所有的BigDecimal计算设置一个“全局精度”?
(例如python中十进制模块的Context.prec() )
谢谢
规格:
Java jre7 SE
Windows 7 (32)
发布于 2012-04-08 03:39:24
(几乎)原始
不那么简单,但您可以创建一个MathContext并将其传递给所有BigDecimal构造函数和执行操作的方法。
修订的
或者,您可以通过提供正确的BigDecimal并使用divide的舍入版本来扩展divide并覆盖您想要使用的任何操作。
public class MyBigDecimal extends BigDecimal {
private static MathContext context = new MathContext(120, RoundingMode.HALF_UP);
public MyBigDecimal(String s) {
super(s, context);
}
public MyBigDecimal(BigDecimal bd) {
this(bd.toString()); // (Calls other constructor)
}
...
public MyBigDecimal divide( BigDecimal divisor ){
return new MyBigDecimal( super.divide( divisor, context ) );
}
public MyBigDecimal add( BigDecimal augend ){
return new MyBigDecimal( super.add( augend ) );
}
...
}发布于 2012-04-08 03:45:21
创建一个带有静态工厂方法的BigDecimalFactory类,它与所有接受MathContext的构造函数相匹配--除了MathContext实例在工厂内部,并且在启动时静态初始化。下面是一个片段:
public class BigDecimalFactory {
public static BigDecimal newInstance (BigInteger unscaledVal, int scale) {
return new BigDecimal (unscaledVal, scale, _mathContext);
}
// . . . other factory methods for other BigDecimal constructors
private static final MathContext _mathContext =
new MathContext (120, BigDecimal.ROUND_HALF_UP);
}发布于 2012-04-08 04:28:25
是否有办法为所有BigDecimal计算设置“全局精度”?
不是的。
您必须创建一个包装类,它将MathContext作为额外的属性。它将需要:
mc,并且(作为一种变体,您可以使用静态实现“全局”MathContext,但仍然需要使用包装来确保使用mc。)
(扩展BigDecimal也能工作,这比包装类更整洁。)
你在评论中这样说:
我真的不想写我自己的十进制模块,我只想知道为什么BigDecimal如此不合作。
(设计问题只能由设计团队明确地回答。但是.
与所有复杂的实用程序类一样,BigDecimal的设计是一种折衷方案,旨在满足多种用例的需求。它也是“强大”和“简单”这两个相互竞争的元要求(错误的词)之间的妥协。
您所拥有的是一个不受特别支持的用例。但是我怀疑如果它得到了很好的支持(例如,一个全局的MathContext控制一切,或者附加到每个BigDecimal上的一个MathContext ),那么这会带来各种其他的复杂性;例如,处理有两个或多个相互竞争的上下文对象需要考虑的操作。这样的问题可以解决..。但是他们很容易给程序员带来“惊喜”,这不是件好事。
当前的方法简单易懂,如果您需要更复杂的东西,您可以实现它。显式地为需要它的操作提供一个MathContext。
https://stackoverflow.com/questions/10060158
复制相似问题