zoukankan      html  css  js  c++  java
  • Python 3.3.2 round函数并非"四舍五入"

    对于一些貌似很简单常见的函数,最好还是去读一下Python文档,否则当你被某个BUG折磨得死去活来时,还不知根源所在.尤其是Python这种不断更新的语言.(python 2.7 的round和3.3.2不一样)

    • 3.3.2官方文档对round的定义

    round(number[ndigits])

    Return the floating point value number rounded to ndigits digits after the decimal point. If ndigits is omitted, it defaults to zero. Delegates to number.__round__(ndigits).

    For the built-in types supporting round(), values are rounded to the closest multiple of 10 to the power minus ndigitsif two multiples are equally close, rounding is done toward the even choice (so, for example, both round(0.5) and round(-0.5) are 0, and round(1.5) is 2). The return value is an integer if called with one argument, otherwise of the same type as number.

    • 举例查看:
    >>> round(1.5)
    2
    >>> round(2.5)
    2
    >>> round(3.5)
    4
    >>> round(4.5)
    4
    >>> round(5.5)
    6
    >>> round(6.5)
    6

    分析定义中的关键语句:

    values are rounded to the closest multiple of 10 to the power minus ndigits
    • 假设round(123.45, 1)=A,那么A在数轴上是离123.45最近的点(the closest),且A保留1位小数.
    • "10 to the power minus ndigits"意思是"10的负ndigits次方",即pow(10, -ndigits).
    • "multiple of n" 表示n的倍数.倍数只能是整数,这个是关键.(可参考维基百科:http://zh.wikipedia.org/wiki/%E5%9B%A0%E6%95%B8)

    那么,例如round(123.45, 1)就表示数轴上离123.45最近的"0.1的X倍".

    X=1时,"0.1的X倍"(即0.1)是离123.45最近的值吗?显然不是,因为当X=1000时,"0.1的X倍"是100,比0.1更靠近123.45.

    按照这个原理进行推导,容易知道当X=1234或1235时,"0.1的X倍"最靠近123.45.那么该取哪个X作为最终结果呢?

    if two multiples are equally close, rounding is done toward the even choice 

    "toward the even choice"意思就是说取偶数.即"0.1的1234倍",即123.4.

    然而,当你测试round(123.45, 1):

    >>> round(123.45, 1)
    123.5

    为什么取偶数呢?是BUG吗?非也,官方文档继续解释:

    Note

    The behavior of round() for floats can be surprising: for example, round(2.675, 2) gives 2.67 instead of the expected 2.68. This is not a bug: it’s a result of the fact that most decimal fractions can’t be represented exactly as a float. See Floating Point Arithmetic: Issues and Limitations for more information

    意思就是说计算机需要先将十进制123.45转换为二进制,这个过程会导致二进制的值比123.45略大(比如123.45000001之类的),那么自然就得到123.5这个值了.

    这种情形非常普遍:

    >>> round(0.05, 1) #should return 0.0
    0.1
    >>> round(0.15, 1) #should return 0.2
    0.1
    >>> round(0.25, 1)
    0.2
    >>> round(0.35, 1) #should return 0.4
    0.3
    >>> round(0.45, 1) #should return 0.4
    0.5

     

  • 相关阅读:
    ios 关于collectionView.performBatchUpdates()方法 --时时更新
    [iOS Xcode注释插件]
    Markdown编辑器简单总结
    [iOS Keychain本地长期键值存储]
    [iOS 利用MapKit和CoreLocation框架打造精简的定位和导航]
    <转>iOS9 Day-by-Day:iOS开发者必须了解的iOS 9新技术与API
    [PHP 作为iOS后台Json格式HTTP通信及文件上传的实现]
    [iOS AFNetworking框架实现HTTP请求、多文件图片上传下载]
    [Java 实现AES加密解密]
    [iOS Hybrid实践:UIWebView中Html中用JS调用OC方法,OC执行JS代码]
  • 原文地址:https://www.cnblogs.com/xiangnan/p/3430579.html
Copyright © 2011-2022 走看看