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 |
|---|---|---|---|
| 24 | 24 | -24 | -24 |
- Round half away from zero
向远离0的方向舍入,也称向无穷方向取整
| +23.5 | +24.5 | -23.5 | -24.5 |
|---|---|---|---|
| 24 | 25 | -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.2 | 3.250 | 3.3 |
|---|---|---|---|
| 误差 | 0.05 | 0.05 |
两者误差相同,按照Round half to even,选择最近的偶数3.2
| 数值 | 3.2 | 3.251 | 3.3 |
|---|---|---|---|
| 误差 | 0.051 | 0.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
IEEE 754舍入的问题的更多相关文章
- IEEE 754 浮点数的四种舍入方式
四种舍入方向: 向最接近的可表示的值:当有两个最接近的可表示的值时首选"偶数"值:向负无穷大(向下):向正无穷大(向上)以及向0(截断). 说明:默认模式是最近舍入(Round t ...
- IEEE二进制浮点数算术标准(IEEE 754)
整理自IEEE 754 IEEE二进制浮点数算术标准(IEEE 754)是20世纪80年代以来最广泛使用的浮点数运算标准,为许多CPU与浮点运算器所采用.这个标准定义了表示浮点数的格式(包括负零-0) ...
- 【转】浮点数与IEEE 754
http://www.cnblogs.com/kingwolfofsky/archive/2011/07/21/2112299.html 浮点数 1. 什么是浮点数 在计算机系统的发展过程中,曾经 ...
- IEEE 754二进制浮点数算术标准
可能很多人都遇到过浮点数精度丢失的问题,下面以JavaScript为例. 1 - 0.9 = 0.09999999999999998 纳尼,不应该是0.1么,怎么变成0.099999999999999 ...
- IEEE 754标准--维基百科
IEEE二进制浮点数算术标准(IEEE 754) 是20世纪80年代以来最广泛使用的浮点数运算标准,为许多CPU与浮点运算器所采用.这个标准定义了表示浮点数的格式(包括负零-0)与反常值(denorm ...
- IEEE 754 浮点数加减运算
电子科技大学 - 计算机组成原理 小数的十进制和二进制转换 移码 定义:[X]移 = X + 2n ( -2n ≤ X < 2n ) X为真值,n为整数的位数 数值位和X的补码相同,符号位与补码 ...
- 玉伯的一道课后题题解(关于 IEEE 754 双精度浮点型精度损失)
前文 的最后给出了玉伯的一道课后题,今天我们来讲讲这题的思路. 题目是这样的: Number.MAX_VALUE + 1 == Number.MAX_VALUE; Number.MAX_VALUE + ...
- IEEE 754标准
IEEE 754-1985 was an industry standard for representing floating-point numbers in computers, officia ...
- 浮点数在计算机内存中的表示(IEEE 754规定1位是符号位,8位是指数,剩下的23位为有效数字)
本文转载自:阮一峰的博客,http://www.ruanyifeng.com/blog/2010/06/ieee_floating-point_representation.html 张玉彬的博客 h ...
随机推荐
- Learning ROS: Managing System dependencies
Download and install the system dependencies for turtlesim: roscd turtlesim cat package.xml rosdep i ...
- MySQL-存储引擎-1
一.MySQL存储引擎 mysql> create table country( -> country_id smallint unsigned not null auto_increme ...
- JavaScript高级程序设计学习笔记之事件
1.事件流 事件流描述的是从页面中接收事件的顺序. 事件冒泡 IE的事件流叫做事件冒泡(event bubbling),即事件开始时由最具体的元素(文档中嵌套层次最深的那个节点)接收,然后逐级向上传播 ...
- Shell中常用的语句
exit 完全中断脚本的执行 break 中断脚本的循环,但是会执行循环外的语句 continue 跳出本次循环,进行下一次循环 进一步了解三者的区别,有如下实验: 执行该脚本: 脚本正常运行情况: ...
- 遇到Web页面禁用鼠标右键操作时,该如何解禁?
在使用Selenium做Web UI自动化测试过程中,经常需要鼠标右击Web页面检查DOM节点,用于获取Web元素的定位信息.一般情况下,绝大多数页面都是能够响应鼠标右击操作的.但出于某些目的,有些W ...
- javascript(2)运算符
### js运算符 1.运算符 1.typeof 获取当前变量类型 运算符(特殊) 2.= 赋值运算符 3.== 简要比较运算符(忽略变量的类型) 4.=== 标准比较运算符(严格变量的类型.判断是否 ...
- sed中传递变量进行替换
sed命令中传递变量 例如:修改配置文件某一个变量的值 配置文件如下: toney@ubantu:/mnt/hgfs/em嵌入式学习记录/shell/shell脚本常见用法$ cat common_u ...
- VUE001. 拖动div盒子(自定义指令v-directives)
拖动div是一个逻辑很简单的需求,监听容器的鼠标按下松开的事件,执行函数通过DOM改变标签的CSS偏移量. 在VUE构建的项目中,通过标签的 @mousedown 和 @mouseup 赋予行为事件, ...
- 写了一年golang,来聊聊进程、线程与协程
本文已收录 https://github.com/lkxiaolou/lkxiaolou 欢迎star. 进程 在早期的单任务计算机中,用户一次只能提交一个作业,独享系统的全部资源,同时也只能干一件事 ...
- Zookeeper Acl权限 超级用户权限 怎么跳过ACL密码/账户验证
Zookeeper的一个节点不知道什么原因无法删除了,查看日志发现是没有权限, 我们之前使用ACL进行Zookeeper节点的权限管理. 可以解决以下三种但不限于以下三种问题: 1.在设置Acl权限时 ...