为什么`2.0-1.1`和`2.0F-1.1F`产生不同的结果?

问题描述 投票:2回答:2

我正在比较Doublefloat值的代码中工作:

class Demo {
    public static void main(String[] args) {
        System.out.println(2.0 - 1.1);
        System.out.println(2.0 - 1.1 == 0.9);

        System.out.println(2.0F - 1.1F);
        System.out.println(2.0F - 1.1F == 0.9F);
        System.out.println(2.0F - 1.1F == 0.9);
    }
}

输出如下:

0.8999999999999999
false
0.9
true
false

我相信Double值比float可以节省更多的精度。

[请说明这一点,看起来float值不是丢失精度,而是double一个丢失?


编辑:@goodvibration我知道0.9不能以任何计算机语言完全保存,我只是很困惑java如何详细地使用它,为什么2.0F - 1.1F == 0.9F,但是2.0 - 1.1 != 0.9,另一个有趣的发现可能会有所帮助:

class Demo {
    public static void main(String[] args) {
        System.out.println(2.0 - 0.9);            // 1.1
        System.out.println(2.0 - 0.9 == 1.1);     // true

        System.out.println(2.0F - 0.9F);          // 1.1
        System.out.println(2.0F - 0.9F == 1.1F);  // true
        System.out.println(2.0F - 0.9F == 1.1);   // false
    }
}

我知道我不能指望浮点数或双精度,只是..无法弄清楚这让我发疯了,这背后的真正目的是什么?为什么2.0 - 0.9 == 1.12.0 - 1.1 != 0.9 ??

java double precision
2个回答
0
投票

弹出测验:以小数表示1/3。

答案:您不能;不完全是。

计算机以二进制计数。还有更多数字“无法完全代表”。就像在十进制问题中,如果只有一小块纸可以写,您可以简单地用0.3333333命名为一天,然后得到一个非常接近的数字,但与1 / 3并不完全相同,计算机也代表分数。

或者,这样考虑:浮点数占用32位;双占64位。32位值只能表示2 ^ 32(约40亿)个不同的数字。但是,即使在0到1之间,也有无限数量的数字。因此,鉴于最多有2 ^ 32个具体的具体数字可以“精确地”表示为浮点数,因此,在约40亿个值的受祝福集合中没有的任何数字都无法表示。您可以从这个40亿个可表示的值池中获得一个值,而不是仅仅出错,它是最接近您想要的值。]

此外,由于计算机以二进制而不是十进制计数,因此您对“可表示”和“不可以表示”的感觉已经关闭。您可能会认为1/3是个大问题,但肯定1/10很容易,对吧?就是0.1,这是一个精确的表示。啊,但是十分之一在十进制中效果很好。毕竟,十进制是基于数字10的,这并不奇怪。但是用二进制?一半,四分之一,八分之一,十六分之一:二进制容易。十分之一?这和第三个难度一样:NOT REPRESENTABLE

0.9本身不是可表示的数字。但是,当您打印浮标时,就是这样。

原因是,打印浮点数/双打是一门艺术,而不是一门科学。假设只有少数数字是可表示的,并且由于二进制v。十进制的原因,这些数字对人类而言并不“自然”,那么您确实需要在数字上添加“取整”策略,否则看起来疯狂(没人想读0.899999999999999999765)。这正是System.out.println及其合作伙伴所做的。

但是您实际上应该控制舍入功能:切勿使用System.out.println打印双精度和浮点型。请改用System.out.printf("%.6f", yourDouble);,在这种情况下,两者都将打印0.9。因为虽然两者都不能真正精确地表示0.9,但最接近浮点数的数字(或者更确切地说,就是取最接近2.0的数字(即2.0)和最接近1.1的数字(不是精确地1.1)),减去它们,然后找到最接近该结果的数字)–即使不是浮点数也打印为0.9,并且不打印为0.9的两倍。


0
投票

floatdouble之间的差异:

© www.soinside.com 2019 - 2024. All rights reserved.