IEEE 754 中的四舍五入到最近值

3
在IEEE 754中,有一种将浮点数值四舍五入的“最近舍入”方法。
但是我不理解定义中的一个条款:
如果两个最接近的可表示值同样接近,则选择其最低有效位为零的那个。
什么是“选择其最低有效位为零的那个”?

1
012345678,在这种情况下,8是最低有效位。它是改变数字最少的位(或数字)。将#8加一,只会增加这个数字。将#0加一,将使其增加10000000。现在,位被存储为0001 0010,之前的只是一个例子。这样做对你有帮助吗? - Emz
所以,如果我们有两个相邻的单精度浮点数,其尾数以二进制形式表示为:1.00000000000000000000001和1.00000000000000000000010,那么选择第二个数字是因为它在最后23位上包含零? - Vitaly
是的,我是这样理解的。 - Emz
1
这也被称为“银行家舍入”(bankers' rounding)。 - Andreas
3个回答

2
看起来我理解了这个问题。单精度和双精度数字可以用32位和64位的二进制序列表示,具体如下:
b bbbbbbbb bbbbbbbbbbbbbbbbbbbbbbb

b bbbbbbbbbbb bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb

这里的b是0或1。 第一组对应于数字的符号。 第二组对应于数字的指数,包括8位(单精度)和11位(双精度)。 第三组对应于数字的尾数,由23位(单精度)和52位(双精度)组成。

因此,对于单精度数字,数字的最低有效位是尾数的第23位,对于双精度数字是尾数的第52位。这是数字的最右边的位。如果这个位是零,它将被选择。

注意: 偶数和奇数仅针对整数值定义。 因此,如果舍入函数只将数字舍入到整数值,则此规则退化为“四舍五入至偶数规则”。

感谢大家的努力。


请将此答案标记为“已接受”。如果其他人有相同的问题,他们将更容易找到答案。 - Emz

1
使用“四舍六入五成双”规则玩得最好的方法是将十六进制表示的双精度数舍入为单精度数,例如在C99或Java编程语言中。
单精度具有23个显式二进制位,因此数字0x1.000000p0、0x1.000002p0、0x1.000004p0等都是单精度数,但其中间的数字不是。
当一个值恰好处于两个连续的单精度浮点数l和u之间时,l和u的二进制展开在符号后的第23位上不同,即1.bbbbbbbbbbbbbbbbbbbbbbbbb * 2^exp的表示法中。这是l和u连续的简单结果。
双精度数0x1.000001p0、0x1.000003p0、0x1.000005p0等恰好处于两个单精度数之间,需要根据“最低有效位为零”的规则进行舍入。
示例C99程序:
#include <stdio.h>
#include <stdlib.h>

int main(int c, char *v[]) {
  double d = 0x1.000001p0;
  for (int i = 0; i < 10; i++) {
    printf("double-precision:%.6a\n"
           "single-precision:%.6a\n\n",
           d, (float) d);
    d += 0x0.000002p0;
  }
}

展示取整如何将单精度值舍入为在小数点后第23位的二进制数字为0的值的结果:
double-precision:0x1.000001p+0
single-precision:0x1.000000p+0
double-precision:0x1.000003p+0 single-precision:0x1.000004p+0
double-precision:0x1.000005p+0 single-precision:0x1.000004p+0
double-precision:0x1.000007p+0 single-precision:0x1.000008p+0
double-precision:0x1.000009p+0 single-precision:0x1.000008p+0
double-precision:0x1.00000bp+0 single-precision:0x1.00000cp+0
double-precision:0x1.00000dp+0 single-precision:0x1.00000cp+0
double-precision:0x1.00000fp+0 single-precision:0x1.000010p+0
double-precision:0x1.000011p+0 single-precision:0x1.000010p+0
double-precision:0x1.000013p+0 single-precision:0x1.000014p+0

0
这只是意味着当遇到平分的情况时,会采用四舍六入五成双的方式来解决。这也被称为银行家舍入。例如,3.5会被舍入为4.0,但4.5会被舍入为4.0。这也会影响那些过大无法精确表示的数字。例如,在32位浮点数中,整数16777219会被舍入为16777220.0而不是16777218.0,因为后者的表示以1结尾。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接