go2goj Asked:2020-11-08 18:42:23 +0000 UTC2020-11-08 18:42:23 +0000 UTC 2020-11-08 18:42:23 +0000 UTC 为什么 Float.MAX_VALUE-1 == Float.MAX_VALUE 为真? 772 为什么 Float.MAX_VALUE-1 == Float.MAX_VALUE 为真? 不会出现此问题的 float 和 double 的最大数字是多少? java 2 个回答 Voted Best Answer Zealint 2020-11-08T21:01:05Z2020-11-08T21:01:05Z 首先,让我们看一个可以阐明情况的类比。想象一下,您只能存储 3 个十进制数字,您需要记下该数字12345。它不起作用,但您可以将其保存为另一种格式:123 * 10**2. 这正是(简单地说)浮点算术的工作原理:只存储数字的最高有效位和顺序(移位、度数、指数——无论你想怎么称呼它)。 现在你想减去一个。好吧,让我们一起尝试:12345 - 1 = 12344。但是,您只能存储 3 位数字,所以我们有123 * 10**2,与原来的完全一样!也就是说,减去单位不会影响情况,因为单位会影响那些没有存储的数字,它可以说是太小了。更多关于这个是这里。在那里,使用一个玩具浮点数格式的例子,有一个关于这个和其他一些意想不到的效果的故事。 接下来,您询问不具有此属性的最大数量是多少。由于浮点类型有 23 位分配给数字(尾数),并且多一位始终为 1,因此我们2**24可以从高达 1 的数字中减去 1,并且将正确减去。然而,更远的2**24和2**25数字以 2 为增量,所以每一秒,当减一时,将在偶数和奇数之间的中间,因此,根据最接近偶数、半偶数舍入规则,数字将向下舍入(甚至)。因此,在这个区间内,所有不能被整除的 EVEN 数4在尝试减去 时都会减少 2 1。其余数字不会减少。例如,一个数33554430(不能被 整除4)变为等于33554428,但是,再次减去1不会改变任何事情。顺便说一句,这个数字33554430=2**25-2是你要求的最大值。但是,如果您需要前一个(减去 1 后获得)也被正常减去,那么最大的将是2**24+2. 减1后得到2**24(即减2),再减1时减1。 对于 double 它将是2**53+2 = 9007199254740994(如果有必要正常减去所有先前的)并且2**54-2 = 18014398509481982(如果在减去 1 后它减少 2 并且再次减去将不会给出结果)。 Alice Magic 2020-11-08T19:18:09Z2020-11-08T19:18:09Z 你可以这样检查: public static void main(String[] args) { float i; for (i = 1; i < 1e38; i *= 10) { System.out.println(i + " " + (Float.MAX_VALUE-i == Float.MAX_VALUE)); } }
首先,让我们看一个可以阐明情况的类比。想象一下,您只能存储 3 个十进制数字,您需要记下该数字
12345。它不起作用,但您可以将其保存为另一种格式:123 * 10**2. 这正是(简单地说)浮点算术的工作原理:只存储数字的最高有效位和顺序(移位、度数、指数——无论你想怎么称呼它)。现在你想减去一个。好吧,让我们一起尝试:
12345 - 1 = 12344。但是,您只能存储 3 位数字,所以我们有123 * 10**2,与原来的完全一样!也就是说,减去单位不会影响情况,因为单位会影响那些没有存储的数字,它可以说是太小了。更多关于这个是这里。在那里,使用一个玩具浮点数格式的例子,有一个关于这个和其他一些意想不到的效果的故事。接下来,您询问不具有此属性的最大数量是多少。由于浮点类型有 23 位分配给数字(尾数),并且多一位始终为 1,因此我们
2**24可以从高达 1 的数字中减去 1,并且将正确减去。然而,更远的2**24和2**25数字以 2 为增量,所以每一秒,当减一时,将在偶数和奇数之间的中间,因此,根据最接近偶数、半偶数舍入规则,数字将向下舍入(甚至)。因此,在这个区间内,所有不能被整除的 EVEN 数4在尝试减去 时都会减少 21。其余数字不会减少。例如,一个数33554430(不能被 整除4)变为等于33554428,但是,再次减去1不会改变任何事情。顺便说一句,这个数字33554430=2**25-2是你要求的最大值。但是,如果您需要前一个(减去 1 后获得)也被正常减去,那么最大的将是2**24+2. 减1后得到2**24(即减2),再减1时减1。对于 double 它将是
2**53+2 = 9007199254740994(如果有必要正常减去所有先前的)并且2**54-2 = 18014398509481982(如果在减去 1 后它减少 2 并且再次减去将不会给出结果)。你可以这样检查: