zoukankan      html  css  js  c++  java
  • 关于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;

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

  • 相关阅读:
    Mybaits 的优点
    mybatis中#{}和${}的区别
    springmvc工作流程
    request对象的主要方法有哪些
    如何决定选用HashMap还是TreeMap?
    队列和栈是什么,列出它们的区别?
    fail-fast与fail-safe有什么区别?
    Collections类是什么?
    哪些集合类提供对元素的随机访问?
    可以作为GC Roots的对象包括哪些
  • 原文地址:https://www.cnblogs.com/liuzhanshan/p/6237849.html
Copyright © 2011-2022 走看看