IEEE 754舍入的问题

写在前面
本文的舍入方法只适用于保留0位或1位小数,个人水平所限,暂时没有发现保留更多小数位的舍入的规律…

IEEE 754的舍入模式

在这里插入图片描述
IEEE 754标准提供了2类,5种舍入模式,在默认情况下一般是Round to nearest。

Directed roundings

  • Round toward 0
    向0舍入,也称截断法
+11.5-11.5
+11.0-11.0
  • Round toward +∞
    向正无穷舍入
+11.5-11.5
+12.0-11.0
  • Round toward −∞
    向负无穷舍入
+11.5-11.5
+11.0-12.0

Rounding to nearest

  • Round half to even
    向最近的偶数舍入
+23.5+24.5-23.5-24.5
2424-24-24
  • Round half away from zero
    向远离0的方向舍入,也称向无穷方向取整
+23.5+24.5-23.5-24.5
2425-24-25

下面是个人的理解
名称里的"half"在舍入一组数据才比较好的体现出来,如下面的代码所示

#include <stdio.h>

int
main( int argc, char **argv )
{
	printf("%.0lf\n", 20.5);
	printf("%.0lf\n", 21.5);
	printf("%.0lf\n", 22.5);
	printf("%.0lf\n", 23.5);
	printf("%.0lf\n", 24.5);
	printf("%.0lf\n", 25.5);
	printf("%.0lf\n", 26.5);
	printf("%.0lf\n", 27.5);
	printf("%.0lf\n", 28.5);
	printf("%.0lf\n", 29.5);
	
	return 0;
}

vs2010运行结果
在这里插入图片描述

gcc version 7.5.0 (Ubuntu 7.5.0-3ubuntu1~18.04) 运行结果
在这里插入图片描述
可见vs2010使用的舍入规则是Round half away from zero,gcc使用的是Round half to even。

mingw的gcc运行结果和vs2010一致。

以Ubuntu的运行结果为例,将原数据和舍入后的数据绘制成散点图
在这里插入图片描述
可见,原数据中有的数字是向上取,有的向下取。

更准确的说:是一半的数据向上取整,另一半的数据向下取整。

从图中可以看出,舍入后的数据在原数值上下摆动,但总体上与原数据相差无几。

这便是我理解的half的含义:有一半的数据向下取整,同时另一半的数据向上取整。Round half to even 也是统计学里抵抗误差常用的舍入策略。

下面我们来看看直接四舍五入的散点图
在这里插入图片描述
可见,直接四舍五入,所有数据都是向上取整的,舍入误差累积后,舍入后的数据总体上就偏离了原数据。

摘录《深入理解计算机系统》第二章 信息的表示和处理

向偶数舍入初看上去好像是个相当随意的目标——有什么理由偏向取偶数呢?为什么不始终把位于两个可表示的值的中间的值都向上舍入呢?使用这种方法的一个问题就是很容易假想到这样的情景:这种方法舍入一组数据,会在计算这些值的平均数中引入统计偏差。我们采用这种方式舍入得到的一组数的平均值将比这些数本身的平均值略高一些。相反,如果我们总是把两个可表示值中间的数字向下舍入,那么舍入后的一组数的平均值将比这些数本身的平均值略低一些。向偶数舍入在大多数现实情况下避免了这种统计偏差。在50%的时间里,它将向上舍入,而在50%的时间里,它将向下舍入。

舍入的具体流程 以gcc为例

在这里插入图片描述

#include <stdio.h>

int
main( int argc, char **argv )
{
	printf("%.1lf\n", 3.250);
	printf("%.1lf\n", 3.251);
	
	return 0;
}
数值3.23.2503.3
误差0.050.05

两者误差相同,按照Round half to even,选择最近的偶数3.2

数值3.23.2513.3
误差0.0510.049

选择误差小的3.3
在这里插入图片描述

参考链接

https://my.oschina.net/aquar/blog/731999

https://en.wikipedia.org/wiki/IEEE_754
https://en.wikipedia.org/wiki/Rounding

https://www.zhihu.com/question/68131179/answer/261539674

http://m.newsmth.net/article/EnglishWorld/40696

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
由MATLAB技术论坛原创,原帖参见http://www.matlabsky.com/viewthread.php?tid=3093 该教程详细介绍了MATLAB的舍入误差原理和计算,并给出实例验证。 由于涉及很多数学公式和图形,帖中不方便展示,下面给出了大概的内容提要,具体参见本帖pdf附件http://www.matlabsky.com/viewthread.php?tid=3093! 舍入误差是计算机进行实数计算是所产生的。之所以产生舍入误差是因为机器中进行的算术运算所涉及的数是有限位的,从而导致计算只能用实际数值的近视表示式来完成。在典型的计算机中,仅实数系统的一个相对小的子集用来表示所有的实数。这个子集包含了正负有理数,且存储了小数和指数部分。 IEEE754-1985二进制浮点运算标准 MATLAB中所有数值都是使用64bit表示的。根据754-1985规定,第一位是符号指示位(S),接下来的11位是指数部分(C),最后称为尾数的52位为小数部分(F),指数的基是2。 X64表示的区间范围 x64=0 10000000011 1011100100010000000000000000000000000000000000000000 y64=0 10000000011 1011100100001111111111111111111111111111111111111111 z64=0 10000000011 1011100100010000000000000000000000000000000000000001 这意味着,二进制机器数x64不仅仅代表十进制的x,还表示x临域内的所有实数,也就是说十进制区间(注意是左闭右开的区间) [(y+x)/2, (x+z)/2)= [15518507114430463/562949953421312, 15518507114430465/562949953421312) 内所有数据都是使用机器数x64表示的。这样机器的截断误差就出现了! 如何确定XMIN和XMAX 从IEEE754-1985的规定,我们容易知道64位机器数能够表示的最小正数,此时第64位为1其它为0,故 xmin=2^(-1023)*(1+0.5^52)≈10^(-308) 在计算小于xmin的数据的时候,MATLAB直接当0处理 同理最大的正数则第1位为0其它为1,故 xmax=2^1024*(2-0.5^52)≈10^308 在计算大于xmax数据时,MATLAB视为Inf X的精度范围求解 二进制数x64的前后一个数,相当于在x64尾数的最后一位加1或减1,故x64与最近的数之间的距离为0.5^52 ,另外指数位会将尾数放大了2^n倍,故最终x的精度为0.5*2^(n-52)(注意必须乘以0.5,原因如上)。故在±0.5*2^(n-52)范围内的数据,MATLAB都用x64表示,也就是认为都是x

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值