Java 带DecimalFormat的BigDecimal格式

Java 带DecimalFormat的BigDecimal格式,java,scale,rounding,bigdecimal,decimalformat,Java,Scale,Rounding,Bigdecimal,Decimalformat,我试图通过将大十进制数舍入到第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 v

我试图通过将大十进制数舍入到第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-向下舍入

我错过了什么

多谢各位

n2: 0.0123456789012345 ==> 0.0123456789012345=0.012345678901235
不,
n2
是完全四舍五入的,点
后n2上的
15位
4
后跟
5
,因此
45
四舍五入为
5

如果您在
之后计算n2上的位数,则它们是
16位
而不是
15位
,因此根据您的模式,您希望对
15位
长度进行四舍五入


你不需要关心数字的数字量,你也不需要关心数字的数字量之前的
通过使用使用
<编码你你不需要关心数字的数字量之前的
<编码你不需要通过使用你不需要关心数字的数字量之前的
<编码你不需要通过使用使用你不需要关心你不需要关心数字的数字之前的数字量通过使用使用<编码你通过使用使用你不需要使用你不需要通过使用你不需要通过使用你不需要使用你不需要关心你不需要关心你不需要通过使用你不需要通过使用你不需要通过使用你不需要关心你不需要关心你不需要关心你之前的数字之前的数字量之前的数字量之前的数字量之前的数字量之前的编码通过使用<编码通过使用<编码通过使用你通过使用你通过使用你通过使用你通过使用<编码通过使用你通过使用你通过使用<编码通过使用你通过使用你通过使用你通过使用<编码通过使用<编码通过使用你通过使用你通过使用通过使用你使用你#############“

您正在为大十进制设置舍入模式。但是输出的最后一部分的四舍五入不是大小数。这是十进制

设置十进制格式的舍入模式:

numberFormat.setRoundingMode(RoundingMode.HALF_UP);

请注意,DecimalFormat能够格式化DecimalFormat实例。在格式化它们之前,不应该将它们转换为double,因为这样做可能会失去精度。

来自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位的初始值

然后,我猜您会因为
格式
方法而获得舍入误差。它采用双精度作为参数,它永远不会精确到您使用的16位数字,而只是一个近似值。因为它是近似值,
n2
可能存储为…23449,而不是…2345


但与Fev一样,在我的计算机上执行程序时,我没有遇到此错误。

您实际上没有使用设置刻度的BigDecimal:

n2.setScale(15, BigDecimal.ROUND_HALF_UP);
该行应为:

n2 = n2.setScale(15, BigDecimal.ROUND_HALF_UP);

更改为该值,它将按预期工作。

为什么要传入有限精度浮点值而不是字符串形式:
“0.0452…”
?我正在从数据库中获取大小数。结果集的结果是这样的。我刚刚用字符串尝试了一下,得到了相同的结果。我不确定“四舍五入大十进制数”是什么意思。程序的输出是字符串,字符串来自两个位置中的任意一个:要么隐式调用Double.toString(d),要么调用numberFormat.format(d),其中d在任何情况下都是Double。BigDecimal对象甚至不会进入图片。