我试图通过将BigDecimal数字舍入到第15位来获得可预测的行为。结果我得到了一些向上或向下舍入。
import java.math.BigDecimal;
import java.math.MathContext;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.text.NumberFormat;
public class NumberTest {
public static void main(String[] args) {
String pattern = "##############0.0##############";
MathContext mc = new MathContext(15, RoundingMode.HALF_UP);
NumberFormat numberFormat = new DecimalFormat(pattern);
BigDecimal n1 = new BigDecimal(0.0452641706926935, mc);
n1.setScale(15, BigDecimal.ROUND_HALF_UP);
BigDecimal n2 = new BigDecimal(0.0123456789012345, mc);
n2.setScale(15, BigDecimal.ROUND_HALF_UP);
System.out.println("n1: "+n1+" ==> "+n1.doubleValue()+"="+numberFormat.format(n1.doubleValue()));
System.out.println("n3: "+n2+" ==> "+n2.doubleValue()+"="+numberFormat.format(n2.doubleValue()));
}
}
Output of my result:
n1: 0.0452641706926935 ==> 0.0452641706926935=0.045264170692694
n2: 0.0123456789012345 ==> 0.0123456789012345=0.012345678901234
n1 - 四舍五入 n2 - 向下舍入
我错过了什么?
谢谢。答案 0 :(得分:2)
您实际上并未使用为其设置比例的BigDecimal:
n2.setScale(15, BigDecimal.ROUND_HALF_UP);
这一行应该是:
n2 = n2.setScale(15, BigDecimal.ROUND_HALF_UP);
更改为,并按预期工作。
答案 1 :(得分:1)
n2: 0.0123456789012345 ==> 0.0123456789012345=0.012345678901235
不,n2
完全向上舍入,点15th
后n2上的.
数字为4
,后跟5
,因此{{1} }向上舍入到45
。
如果您计算5
之后{n = 2}的数字位数.
而不是16 digits
,那么根据您的模式,您希望在点{15
之后向前舍入15 digit
长度{1}}
顺便说一下,使用.
,您无需关心.
之前的数字位数,您只需使用"##############0.0##############"
。
答案 2 :(得分:1)
您正在为BigDecimal设置舍入模式。但是,对输出的最后一部分进行舍入的不是BigDecimal。这是DecimalFormat。
设置DecimalFormat的舍入模式:
numberFormat.setRoundingMode(RoundingMode.HALF_UP);
请注意,DecimalFormat能够格式化DecimalFormat实例。在格式化它们之前,不应该将它们转换为double,因为这样做会丢失精度。
答案 3 :(得分:1)
来自MathContext的Java文档:
The base-independent settings are:
precision: the number of digits to be used for an operation; results are rounded to this precision
roundingMode: a RoundingMode object which specifies the algorithm to be used for rounding.
您不在此处执行任何操作,因此您的BigInteger对象不会被舍入。因此,当您打印值时,n1
和n2
仍然包含16位数的初始值。
然后,我猜你因format
方法而得到舍入错误。它需要一个double作为参数,它永远不会是你使用的16位数,但只是一个近似值。因为它是近似值,n2
可能已存储为... 23449而不是...... 2345。
但是和Fev一样,我在计算机上执行程序时没有收到此错误。