Java浮点澄清

anu*_*har 3 java floating-point

我正在阅读约书亚布洛赫的Java益智游戏.在谜题28中,我无法理解以下段落 -

这是有效的,因为浮点值越大,值与其后继值之间的距离越大.这种浮点值的分布是它们用固定数量的有效位表示的结果.将1添加到足够大的浮点值将不会更改该值,因为它不会"弥合"与其后继者之间的差距.

  1. 为什么较大的浮点值的值与后继值之间的距离较大?
  2. 在这种情况下Integer,我们添加一个来获得下一个Integer,但是如果float,我们如何获得下一个float值?如果我有IEEE-754格式的浮点值,我是否在尾数部分添加1以获得下一个浮点数?

Gra*_*ths 6

想象一下基于十进制的格式,你只允许设置前5个值(即你的尾数是长度5).对于小数字你会没事的:1.0000,12.000,125.00

但对于较大的数字,您将开始截断eg1113500.下一个可表示的数字是1113600,即100更大.中间的任何值都不能以此格式表示.如果您正在读取此范围内的值,则必须截断它 - 找到匹配的最接近的表示,即使它不准确.

数字越大,问题就越严重.如果我达到34567800000那么下一个可表示的数字将是34567900000,这是1000000或100万的差距.通过这种方式,您可以看到表示之间的差异取决于大小.

在另一个极端,对于小值0.0001,下一个可表示的值是0.0002,因此差距仅为0.0001.

浮点值具有相同的原理,但采用二进制编码(2的幂而不是10的幂).


Ted*_*opp 5

您可以将浮点视为基础2科学记数法.在浮点数中,您被限制为尾数(也就是有效数字)和指数的固定位数.多少取决于您使用的是float(24位)还是double(53位).

考虑基数为10的科学记数法会更为熟悉.想象一下,尾数限于一个整数,并始终由3位有效数字表示.现在考虑这个表示中的这两对连续数字:

  • 100 x 10 0和101 x 10 0(100和101)
  • 100 x 10 1和101 x 10 1(1000和1010)

注意,第一对中的数字之间的距离(又称差异)是1,而第二对中的距离是10.在两对中,尾数相差1,这是整数之间可以存在的最小差异,但是差异由指数缩放.这就是为什么大数字在浮点数之间有更大的步数(你的第一个问题).

关于第二个问题,让我们看看将1(100 x 10 -2)加到数字1000(100 x 10 1):

  • 100 x 10 1 + 100 x 10 -2 = 1001 x 10 0

但我们仅限于尾数中的三位有效数字,因此最后一个数字被标准化(在舍入后)到:

  • 100 x 10 1

这使我们回到1000.要更改浮点值,您需要添加该数字与下一个数字之间差异的至少一半; 这个最小差异随着数字的大小而变化.

二进制浮点正在发生同样的事情.有更多细节(例如,归一化,保护数字,隐含小数点,隐含位),您可以在优秀的文章中了解每个计算机科学家应该知道的关于浮点运算的内容