Java float比double更精确?

时间:2013-10-18 07:34:17

标签: java floating-accuracy floating-point-precision double-precision

代码:

class Main {
    public static void main (String[] args) {
        System.out.print("float: ");
        System.out.println(1.35f-0.00026f);
        System.out.print("double: ");
        System.out.println(1.35-0.00026);
    }
}

输出:

float: 1.34974
double: 1.3497400000000002

???浮点数得到了正确的答案,但是双倍是从没有地方添加额外的东西,为什么?

不应该比浮动更精确吗?

3 个答案:

答案 0 :(得分:10)

浮点数是4个字节宽,而双数是8个字节宽。

检查What Every Computer Scientist Should Know About Floating-Point Arithmetic

当然双精度具有更高的精度,因此它的舍入误差略小。

  

将无数多个实数压缩成有限数量的位   需要近似的表示。虽然有无限的   许多整数,在大多数程序中,整数计算的结果都可以   以32位存储。相反,给定任意数量的位,   大多数带有实数的计算都会产生数量   不能使用那么多位来精确表示。 因此   浮点计算的结果通常必须按顺序舍入   适应它的有限表示。这个舍入误差是   浮点计算的特征。

旁注: -

我建议如果你想要精确的十进制值,那么使用java.math.BigDecimal

答案 1 :(得分:3)

  

如果您对转换 double 值的规则有所了解   到字符串,由 Double.toString [Java-API]的文档指定,您知道该程序打印的最小小数足以区分double值   来自最近的邻居,前后至少有一位数字   小数点。

检查Joshua Bloch的 Java Puzzlers:陷阱,陷阱和角落案例 - 难题2:变革的时间。他在那一章解释了这个问题。

答案 2 :(得分:3)

这是因为浮点计算的数字机制。 此外,当java尝试打印浮点值时,它会截断尾随零。 而且,您知道, double 类型使用8个字节而 float 使用4.因此 double 预设更大。

因此,当java计算你的浮点值时,它会得到类似1.3497400的东西并在输出之前截断它。 当java计算你的double值时,它会得到更多的数字,所以你得到了这样的结果。

尝试执行此简单示例以便更好地理解:

public class Test {
    public static void main( String[] args ) {
        float sum = 0;
        for (int i = 1; i <= 10; i++) {
            sum += 0.1;
        }
        System.out.println( sum );
    }
}

public class Test {
    public static void main( String[] args ) {
        double sum = 0;
        for (int i = 1; i <= 10; i++) {
            sum += 0.1;
        }
        System.out.println( sum );
    }
}