写在前面
本文的舍入方法只适用于保留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舍入的问题的更多相关文章

  1. IEEE 754 浮点数的四种舍入方式

    四种舍入方向: 向最接近的可表示的值:当有两个最接近的可表示的值时首选"偶数"值:向负无穷大(向下):向正无穷大(向上)以及向0(截断). 说明:默认模式是最近舍入(Round t ...

  2. IEEE二进制浮点数算术标准(IEEE 754)

    整理自IEEE 754 IEEE二进制浮点数算术标准(IEEE 754)是20世纪80年代以来最广泛使用的浮点数运算标准,为许多CPU与浮点运算器所采用.这个标准定义了表示浮点数的格式(包括负零-0) ...

  3. 【转】浮点数与IEEE 754

    http://www.cnblogs.com/kingwolfofsky/archive/2011/07/21/2112299.html 浮点数 1.   什么是浮点数 在计算机系统的发展过程中,曾经 ...

  4. IEEE 754二进制浮点数算术标准

    可能很多人都遇到过浮点数精度丢失的问题,下面以JavaScript为例. 1 - 0.9 = 0.09999999999999998 纳尼,不应该是0.1么,怎么变成0.099999999999999 ...

  5. IEEE 754标准--维基百科

    IEEE二进制浮点数算术标准(IEEE 754) 是20世纪80年代以来最广泛使用的浮点数运算标准,为许多CPU与浮点运算器所采用.这个标准定义了表示浮点数的格式(包括负零-0)与反常值(denorm ...

  6. IEEE 754 浮点数加减运算

    电子科技大学 - 计算机组成原理 小数的十进制和二进制转换 移码 定义:[X]移 = X + 2n ( -2n ≤ X < 2n ) X为真值,n为整数的位数 数值位和X的补码相同,符号位与补码 ...

  7. 玉伯的一道课后题题解(关于 IEEE 754 双精度浮点型精度损失)

    前文 的最后给出了玉伯的一道课后题,今天我们来讲讲这题的思路. 题目是这样的: Number.MAX_VALUE + 1 == Number.MAX_VALUE; Number.MAX_VALUE + ...

  8. IEEE 754标准

    IEEE 754-1985 was an industry standard for representing floating-point numbers in computers, officia ...

  9. 浮点数在计算机内存中的表示(IEEE 754规定1位是符号位,8位是指数,剩下的23位为有效数字)

    本文转载自:阮一峰的博客,http://www.ruanyifeng.com/blog/2010/06/ieee_floating-point_representation.html 张玉彬的博客 h ...

随机推荐

  1. JavaSE基础之Java中的数据类型

    基本数据类型:8个 整数类型(4):byte short int long 浮点类型(2):float double 字符类型:char 布尔类型:boolean 引用数据类型:3个 数组 类:cla ...

  2. zset类型数据的操作指令

    1. 也可以追加数据 2. 3. 4. 5. 6. 7. 8. 9.

  3. Linux--MySQL 日志管理、备份与恢复

    MySQL 日志管理.备份与恢复一.MySQL 日志管理二.数据库备份的重要性与分类  1.数据备份的重要性  2.从物理与逻辑的角度,备份分为  3.从数据库的备份策略角度,备份可分为三.常见的备份 ...

  4. TDSQL(MySQL版)之DB组件升级

    随着数据库产品的更新迭代,修复bug等等,产品避免不了会出现升级的需求.TDSQL(MysqL版)也会有这方面的需求.接下来我就说说如何对现有TDSQL(MySQL版)集群组件进行升级,而不影响业务. ...

  5. 被面试官问懵:TCP 四次挥手收到乱序的 FIN 包会如何处理?

    摘要:收到个读者的问题,他在面试的时候,被搞懵了,因为面试官问了他这么一个网络问题. 本文分享自华为云社区<TCP 四次挥手收到乱序的 FIN 包会如何处理?>,作者:小林coding . ...

  6. Junit5快速入门指南-3

    Fixtures 是测试中非常重要的一部分.他们的主要目的是建立一个固定/已知的环境状态以确保 测试可重复并且按照预期的方式运行.比如在app测试中 基类@BeforeClass 配置初始化,初始化d ...

  7. github上使用C语言实现的线程池

    网上介绍线程池的知识很多,但是在代码实现上介绍的又不是那么多.而且给人的一种感觉就是:你的这种实现是正规的方式还是你自己的实现? 如果有这么个疑问,且想找一个靠谱的代码拿来使用,那么这个项目是个不错的 ...

  8. MySQL实战45讲(06--10)-笔记

    目录 06 | 全局锁和表锁 :给表加个字段怎么有这么多阻碍? 全局锁 表级锁 小结 07 | 行锁功过:怎么减少行锁对性能的影响? 死锁和死锁检测 08 | 事务到底是隔离的还是不隔离的? &quo ...

  9. Nginx rewrite跳转 location匹配

    目录: 一.常用的Nginx 正则表达式 二.location 三.rewrite 一.常用的Nginx 正则表达式 1 ^ :匹配输入字符串的起始位置 2 $ :匹配输入字符串的结束位置 3 * : ...

  10. HearthbuddyHelper已经开源

    https://github.com/V-arc/HearthbuddyHelper 只是为了稳定,没耗时多久写的一个中控,只是在逐渐堆加,并未进行重构. 通过写这个感受到自己对异步和wpf的理解还有 ...