zoukankan      html  css  js  c++  java
  • 谈谈关于Python里面小数点精度控制的问题

    基础

    浮点数是用机器上浮点数的本机双精度(64 bit)表示的。提供大约17位的精度和范围从-308到308的指数。和C语言里面的double类型相同。Python不支持32bit的单精度浮点数。如果程序需要精确控制区间和数字精度,可以考虑使用numpy扩展库。

    Python 3.X对于浮点数默认的是提供17位数字的精度。

    关于单精度和双精度的通俗解释:

    单精度型和双精度型,其类型说明符为float 单精度说明符,double 双精度说明符。在Turbo C中单精度型占4个字节(32位)内存空间,其数值范围为3.4E-38~3.4E+38,只能提供七位有效数字。双精度型占8 个字节(64位)内存空间,其数值范围为1.7E-308~1.7E+308,可提供16位有效数字。

    要求较小的精度

    将精度高的浮点数转换成精度低的浮点数。

    1.round()内置方法

    这个是使用最多的,刚看了round()的使用解释,也不是很容易懂。round()不是简单的四舍五入的处理方式。

    For the built-in types supporting round(), values are rounded to the closest multiple of 10 to the power minus ndigits; if 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).

    1
    2
    3
    4
    5
    6
    7
    8
    >>> round(2.5)
    2
    >>> round(1.5)
    2
    >>> round(2.675)
    3
    >>> round(2.6752)
    2.67

     round()如果只有一个数作为参数,不指定位数的时候,返回的是一个整数,而且是最靠近的整数(这点上类似四舍五入)。但是当出现.5的时候,两边的距离都一样,round()取靠近的偶数,这就是为什么round(2.5) = 2。当指定取舍的小数点位数的时候,一般情况也是使用四舍五入的规则,但是碰到.5的这样情况,如果要取舍的位数前的小树是奇数,则直接舍弃,如果偶数这向上取舍。看下面的示例:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    >>> round(2.6352)
    2.63
    >>> round(2.6452)
    2.65
    >>> round(2.6552)
    2.65
    >>> round(2.6652)
    2.67
    >>> round(2.6752)
    2.67

     2. 使用格式化

    效果和round()是一样的。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    >>> a = ("%.2f" % 2.635)
    >>> a
    '2.63'
    >>> a = ("%.2f" % 2.645)
    >>> a
    '2.65'
    >>> a = int(2.5)
    >>> a
    2

    要求超过17位的精度分析

    python默认的是17位小数的精度,但是这里有一个问题,就是当我们的计算需要使用更高的精度(超过17位小数)的时候该怎么做呢?

    1. 使用格式化(不推荐)

    1
    2
    3
    >>> a = "%.30f" % (1/3)
    >>> a
    '0.333333333333333314829616256247'

     可以显示,但是不准确,后面的数字往往没有意义。

    2. 高精度使用decimal模块,配合getcontext

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    >>> from decimal import *
    >>> print(getcontext())
    Context(prec=28, rounding=ROUND_HALF_EVEN, Emin=-999999, Emax=999999, capitals=1, clamp=0, flags=[], traps=[InvalidOperation, DivisionByZero, Overflow])
    >>> getcontext().prec = 50
    >>> b = Decimal(1)/Decimal(3)
    >>> b
    Decimal('0.33333333333333333333333333333333333333333333333333')
    >>> c = Decimal(1)/Decimal(17)
    >>> c
    Decimal('0.058823529411764705882352941176470588235294117647059')
    >>> float(c)
    0.058823529411764705

     默认的context的精度是28位,可以设置为50位甚至更高,都可以。这样在分析复杂的浮点数的时候,可以有更高的自己可以控制的精度。其实可以留意下context里面的这rounding=ROUND_HALF_EVEN 参数。ROUND_HALF_EVEN, 当half的时候,靠近even.

    关于小数和取整

    既然说到小数,就必然要说到整数。一般取整会用到这些函数:

    1. round()

    这个不说了,前面已经讲过了。一定要注意它不是简单的四舍五入,而是ROUND_HALF_EVEN的策略。

    2. math模块的ceil(x)

    取大于或者等于x的最小整数。

    3. math模块的floor(x)

    去小于或者等于x的最大整数。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    >>> from math import ceil, floor
    >>> round(2.5)
    2
    >>> ceil(2.5)
    3
    >>> floor(2.5)
    2
    >>> round(2.3)
    2
    >>> ceil(2.3)
    3
    >>> floor(2.3)
    2
    >>>
  • 相关阅读:
    取得窗口大小和窗口位置兼容所有浏览器的js代码
    一个简单易用的导出Excel类
    如何快速启动chrome插件
    网页表单设计案例
    Ubuntu下的打包解包
    The source file is different from when the module was built. Would you like the debugger to use it anyway?
    FFisher分布
    kalman filter
    Group delay Matlab simulate
    24位位图格式解析
  • 原文地址:https://www.cnblogs.com/ShaYeBlog/p/7646649.html
Copyright © 2011-2022 走看看