Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/400.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
java.math.BigDecimal并不总是用于保留两位小数?_Java - Fatal编程技术网

java.math.BigDecimal并不总是用于保留两位小数?

java.math.BigDecimal并不总是用于保留两位小数?,java,Java,我试图找出几种方法来保持双精度值的两位小数。目前,我尝试了以下5种方法 使用java.math.BigDecimal 使用java.text.DecimalFormat 使用java.text.NumberFormat 使用java.util.Formatter 使用String.format 这5种方法的结果基本一致。但是,在某些场景中,java.math.BigDecimal与其他4种方法的结果不同 以双值100.0050D为例: 使用java.math.BigDecimal时,在我的代

我试图找出几种方法来保持双精度值的两位小数。目前,我尝试了以下5种方法

  • 使用java.math.BigDecimal
  • 使用java.text.DecimalFormat
  • 使用java.text.NumberFormat
  • 使用java.util.Formatter
  • 使用String.format
这5种方法的结果基本一致。但是,在某些场景中,java.math.BigDecimal与其他4种方法的结果不同

以双值100.0050D为例:

使用java.math.BigDecimal时,在我的代码中返回100.00。但是,其他4个方法返回100.01。结果不一致。

实际上,使用的是圆滑模式。我的问题来了:

在下面的代码中使用java.math.BigDecimal保留两位小数和双精度值,我有什么遗漏吗?

还是java.math.BigDecimal类中的一个小缺陷?

请帮我解决这个问题。先谢谢你

此外,我不确定它在不同的JDK版本中是否有所不同,只需提供我使用的JDK版本是1.7.0_25的信息即可

代码如下:

public final class PrecisionTest {

    private PrecisionTest() {
    }

    public static String format1(double value) {

        BigDecimal bd = new BigDecimal(value);
        bd = bd.setScale(2, RoundingMode.HALF_UP);
        return bd.toString();
    }

    public static String format2(double value) {

        DecimalFormat df = new DecimalFormat("0.00");
        df.setRoundingMode(RoundingMode.HALF_UP);
        return df.format(value);
    }

    public static String format3(double value) {

        NumberFormat nf = NumberFormat.getNumberInstance();
        nf.setMaximumFractionDigits(2);
        nf.setMinimumFractionDigits(2);
        nf.setRoundingMode(RoundingMode.HALF_UP);
        nf.setGroupingUsed(false);
        return nf.format(value);
    }

    public static String format4(double value) {
        return new Formatter().format("%.2f", value).toString();
    }

    public static String format5(double value) {

        return String.format("%.2f", value).toString();
    }
}
public class Main {

    public static void main(String[] args) {   

        double[] testData = new double[] { 100.123D, 1234567.897D, 100.0050D,   
                80.0051D,-100245.3658D};   

        for (double value : testData) {   
            System.out.println(PrecisionTest.format1(value));   
            System.out.println(PrecisionTest.format2(value));   
            System.out.println(PrecisionTest.format3(value));   
            System.out.println(PrecisionTest.format4(value));   
            System.out.println(PrecisionTest.format5(value));   
        }   
    }   
}
简单测试代码如下:

public final class PrecisionTest {

    private PrecisionTest() {
    }

    public static String format1(double value) {

        BigDecimal bd = new BigDecimal(value);
        bd = bd.setScale(2, RoundingMode.HALF_UP);
        return bd.toString();
    }

    public static String format2(double value) {

        DecimalFormat df = new DecimalFormat("0.00");
        df.setRoundingMode(RoundingMode.HALF_UP);
        return df.format(value);
    }

    public static String format3(double value) {

        NumberFormat nf = NumberFormat.getNumberInstance();
        nf.setMaximumFractionDigits(2);
        nf.setMinimumFractionDigits(2);
        nf.setRoundingMode(RoundingMode.HALF_UP);
        nf.setGroupingUsed(false);
        return nf.format(value);
    }

    public static String format4(double value) {
        return new Formatter().format("%.2f", value).toString();
    }

    public static String format5(double value) {

        return String.format("%.2f", value).toString();
    }
}
public class Main {

    public static void main(String[] args) {   

        double[] testData = new double[] { 100.123D, 1234567.897D, 100.0050D,   
                80.0051D,-100245.3658D};   

        for (double value : testData) {   
            System.out.println(PrecisionTest.format1(value));   
            System.out.println(PrecisionTest.format2(value));   
            System.out.println(PrecisionTest.format3(value));   
            System.out.println(PrecisionTest.format4(value));   
            System.out.println(PrecisionTest.format5(value));   
        }   
    }   
}

100.005的双精度表示不准确,略小于100.005:

scala> new java.math.BigDecimal(100.0050)
res0: java.math.BigDecimal = 100.0049999999999954525264911353588104248046875
因此,当您设置缩放和舍入模式时,它会向下舍入到100.00

另一方面,使用字符串构造BigDecimal的效果与预期一样:

scala> new java.math.BigDecimal("100.0050")
res2: java.math.BigDecimal = 100.0050

scala> res2.setScale(2, java.math.RoundingMode.HALF_UP).toString
res3: java.lang.String = 100.01

100.005的双精度表示不准确,略小于100.005:

scala> new java.math.BigDecimal(100.0050)
res0: java.math.BigDecimal = 100.0049999999999954525264911353588104248046875
因此,当您设置缩放和舍入模式时,它会向下舍入到100.00

另一方面,使用字符串构造BigDecimal的效果与预期一样:

scala> new java.math.BigDecimal("100.0050")
res2: java.math.BigDecimal = 100.0050

scala> res2.setScale(2, java.math.RoundingMode.HALF_UP).toString
res3: java.lang.String = 100.01
double[]testData=new double[]{100.123D,1234567.897D,100.0050D,
80.0051D,-100245.3658D}

问题就在这里。与BigDecimal无关。这些数字不能用浮点表示。尝试从值的字符串表示形式初始化BigDecimal

double[]testData=new double[]{100.123D,1234567.897D,100.0050D,
80.0051D,-100245.3658D}


问题就在这里。与BigDecimal无关。这些数字不能用浮点表示。尝试从值的字符串表示形式初始化BigDecimal。

您是指BigDecimal而不是BigInteger吗?是的。它是关于java.math.BigDecimal而不是java.math.biginger的。你是指BigDecimal而不是biginger吗?是的。这是关于java.math.BigDecimal的,不是关于java.math.biginger的。谢谢你的回答。谢谢你的回答。谢谢你的信息。谢谢你的信息。