• 关于C/C++的四舍五入方向


    今天在刷题过程中发现了一个特别奇怪的现象,printf() 的精度控制不是按照4舍5入,而是按照5舍6入,

    例如:

    printf("%.2f
    ",0.145)
    printf("%.2f
    ",0.146)

    结果分别为

    0.14
    0.15

    随后的实验中,有一个更加奇怪的现象

    printf("%.2f
    ",0.155)

    的结果为

    0.16

    这就很是奇怪了,一会四舍五入,一会五舍六入的。。。。。

    原来这是因为IEEE 754标准中对浮点数舍入方向的规定,参见这篇博客

    http://www.cnblogs.com/bossin/archive/2007/04/08/704567.html

    下面摘抄关于舍入规定的片段:

    四种舍入方向:

    向最接近的可表示的值;当有两个最接近的可表示的值时首选“偶数”值;向负无穷大(向下);向正无穷大(向上)以及向0(截断)。

    说明:舍入模式也是比较容易引起误解的地方之一。我们最熟悉的是四舍五入模式,但是,IEEE 754标准根本不支持,它的默认模式是最近舍入(Round to Nearest),它与四舍五入只有一点不同,对.5的舍入上,采用取偶数的方式。举例比较如下:

    例2:

    最近舍入模式:Round(0.5) = 0; Round(1.5) = 2; Round(2.5) = 2;

    四舍五入模式:Round(0.5) = 1; Round(1.5) = 2; Round(2.5) = 3;

    主要理由:由于字长有限,浮点数能够精确表示的数是有限的,因而也是离散的。在两个可以精确表示的相邻浮点数之间,必定存在无穷多实数是IEEE浮点数所无法精确表示的。如何用浮点数表示这些数,IEEE 754的方法是用距离该实数最近的浮点数来近似表示。但是,对于.5,它到0和1的距离是一样近,偏向谁都不合适,四舍五入模式取1,虽然银行在计算利息时,愿意多给0.5分钱,但是,它并不合理。例如:如果在求和计算中使用四舍五入,一直算下去,误差有可能越来越大。机会均等才公平,也就是向上和向下各占一半才合理,在大量计算中,从统计角度来看,高一位分别是偶数和奇数的概率正好是50% : 50%。至于为什么取偶数而不是奇数,大师Knuth有一个例子说明偶数更好,于是一锤定音。最近舍入模式在C/C++中没有相应的函数,当然,IEEE754以及x86 FPU的默认舍入模式是最近舍入,也就是每次浮点计算结果都采用最近舍入模式,除非用程序显式设置为其它三种舍入模式。

    另外三种舍入模式,简要说明。

    向0(截断)舍入:C/C++的类型转换。(int) 1.324 = 1,(int) -1.324 = -1;

    向负无穷大(向下)舍入:C/C++函数floor()。例如:floor(1.324) = 1,floor(-1.324) = -2。

    向正无穷大(向上)舍入:C/C++函数ceil()。ceil(1.324) = 2。Ceil(-1.324) = -1;

    后两种舍入方法据说是为了数值计算中的区间算法,但很少听说哪个商业软件使用区间算法。

  • 相关阅读:
    C++ 二元作用域运算符(::)
    C 桶排序
    C 递归的选择排序
    C 归并算法
    C 可变长实参列表
    C条件编译的一些例子
    C实现将中缀算术式转换成后缀表达式
    Activiti6-数据库配置-dbconfig(学习笔记)
    idea在Terminal中使用maven指令
    Spring Boot的web开发
  • 原文地址:https://www.cnblogs.com/liuzhanshan/p/6237849.html
Copyright © 2020-2023  润新知