java - 为什么在 Java 中构造 BigDecimal 时 Double.toString 的行为与 MathContext.DECIMAL64 不同?

标签 java double rounding bigdecimal floating-point-precision

对我来说,Double 似乎应该遵循与 MathContext.DECIMAL64 中使用的 IEEE 标准相同的规则,但是,在这种情况下,我会得到不同的行为:

import java.math.BigDecimal;
import java.math.MathContext;

public class BigDecimalTest {

    public static void main(String[] args) {

        double foo = 8.7;

        System.out.println(new BigDecimal(foo, MathContext.DECIMAL64));
        System.out.println(new BigDecimal(Double.toString(foo)));

    }
}

输出:

8.699999999999999
8.7

最佳答案

A BigDecimal 任意精度带符号的十进制数。另一方面,double 是一个 float ,因此它暗示了对所表示的数字的一些印象。

当您尝试从 double 创建 Bigdecimal 时,您会得到 de double 表示的值,在您的示例中为 8.699999999999999。原因是 double 变量并不能真正保持准确的 8.7。有关大小数的更多信息,请访问

http://goo.gl/tRMLhA

当您将数字表示为字符串时,“8.7”​​值由 to string 方法返回,这就是分配给 Bigdecimal 的值。方法 toString 使用一些 roools 将 double 值表示为 String 看看

http://docs.oracle.com/javase/7/docs/api/java/lang/Double.html#toString(double)&bwsCriterion=toString&bwsMatch=3

当您使用 MathContext.DECIMAL64 时,您是在说“好吧,我知道双数存在一些缺陷,所以我希望您使用 16 位的精度和四舍五入模式进行四舍五入”而这正是您得到的结果. Java 取 8.7 的 double 表示即 8.6999999999999993 并将其四舍五入为 16 位结果为 8.699999999999999 因为数字 17 是“3”,因此四舍五入的结果是保留数字 16,因为它是 9。

有关 MathContext.DECIMAL64 含义的信息: http://goo.gl/fVUehh

如果你想得到 8.7,只需使用低于 16 位的精度。

示例代码

/**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub

           double foo = 8.7;

            System.out.println(new BigDecimal(foo, MathContext.DECIMAL64));
            System.out.println(new BigDecimal(foo, new MathContext(16)));
            System.out.println(new BigDecimal(foo, new MathContext(17)));

            System.out.println(new BigDecimal(foo, new MathContext(1)));
            System.out.println(new BigDecimal(foo, new MathContext(2)));
            System.out.println(new BigDecimal(foo, new MathContext(3)));
            System.out.println(new BigDecimal(foo, new MathContext(15)));

            System.out.println(new BigDecimal(Double.toString(foo)));

    }

输出

8.699999999999999
8.699999999999999
8.6999999999999993
9
8.7
8.70
8.70000000000000
8.7

关于 BigDecimal 和 double 的更多信息

https://blogs.oracle.com/CoreJavaTechTips/entry/the_need_for_bigdecimal

关于java - 为什么在 Java 中构造 BigDecimal 时 Double.toString 的行为与 MathContext.DECIMAL64 不同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19431689/

相关文章:

java - 有效的 Jar 分类器

C++/WinAPI GDI+ 双缓冲

ios - 为什么在格式化数字时NSString类会出现不一致的舍入?

java - Java 中的往返转换

java自动将数组大小加倍

php - 四舍五入机制至最接近的 0.05

python - 如何将 Avg() 舍入到最接近的整数? Django

java - 将添加的字符串返回到

java - 将 Map 转换为 QueryString

java - Android:如何使用 XML 绘制 8 个相等的矩形以适合屏幕宽度