推荐学习书目
› Learn Python the Hard Way
Python Sites
› PyPI - Python Package Index
› http://diveintopython.org/toc/index.html
› Pocoo
值得关注的项目
› PyPy
› Celery
› Jinja2
› Read the Docs
› gevent
› pyenv
› virtualenv
› Stackless Python
› Beautiful Soup
› 结巴中文分词
› Green Unicorn
› Sentry
› Shovel
› Pyflakes
› pytest
Python 编程
› pep8 Checker
Styles
› PEP 8
› Google Python Style Guide
› Code Style from The Hitchhiker's Guide
djj510620510
V2EX  ›  Python

Python3 Decimal + round 函数 小坑

  •  
  •   djj510620510 · Jul 22, 2019 · 3945 views
    This topic created in 2669 days ago, the information mentioned may be changed or developed.
    from decimal import Decimal
    
    round(Decimal(0.123456789), 3) + Decimal(0.01)  # out: Decimal('0.1330000000000000002081668171')
    
    round(Decimal(0.123456789) + Decimal(0.01), 3)  # out: Decimal('0.133')
    

    测试环境 python 3.6.5 + ipython

    :D

    20 replies  •  2019-07-23 09:20:25 +08:00
    nooper
    nooper
    Jul 22, 2019
    1
    不是 python 的坑,是所有计算机指令的问题。 你在好好查一下,有专门的文档 decimal round_up 等处理这个问题。
    chenstack
    chenstack
    Jul 22, 2019❤️5
    2
    >>> round(Decimal('0.123456789'), 3) + Decimal('0.01')
    Decimal('0.133')

    Decimal 初始化时不要传 float 类型,要传字符串,因为传 float 时,float 值本身就有精度丢失问题
    >>> Decimal(0.01)
    Decimal('0.01000000000000000020816681711721685132943093776702880859375')
    >>> Decimal('0.01')
    Decimal('0.01')
    lyy16384
    lyy16384
    Jul 22, 2019
    3
    我试了没有 round 也一样
    Decimal(0.123) + Decimal(0.01)
    chenstack
    chenstack
    Jul 22, 2019
    4
    Construct a new Decimal object. 'value' can be an integer, string, tuple, or another Decimal object. If no value is given, return Decimal('0'). The context does not affect the conversion and is only passed to determine if the InvalidOperation trap is active.
    XIVN1987
    XIVN1987
    Jul 22, 2019
    5
    使用 decimal 不就是为了避免 float 的误差吗?

    对 decimal 使用 round 不就把精确表示又带回了 float 的不精确表示了吗?
    jingniao
    jingniao
    Jul 22, 2019 via Android
    6
    对 decimal round 有自己的函数
    djj510620510
    djj510620510
    OP
    Jul 22, 2019
    7
    @chenstack 感谢告知 :D

    @XIVN1987 但是 round 返回的还是 decimal 类型
    XIVN1987
    XIVN1987
    Jul 22, 2019
    8
    @djj510620510
    抱歉,我看错了,,我以为是把 decimal 加法结果传给了 round,,
    djj510620510
    djj510620510
    OP
    Jul 22, 2019
    9
    @jingniao 还真是。。。。
    djj510620510
    djj510620510
    OP
    Jul 22, 2019
    10
    @jingniao 但按照 python 设计理念,不是应该 Decimal 类里实现一个__round__吗,然后这个__round__的逻辑跟 decimal.round 的逻辑一样。
    hjq98765
    hjq98765
    Jul 22, 2019
    11
    我还是为是说 [四舍六入五成双]
    djj510620510
    djj510620510
    OP
    Jul 22, 2019
    12
    @hjq98765 应该 JS 才会出现吧 /doge
    pkuphy
    pkuphy
    Jul 22, 2019
    13
    >>> round(1.5)
    2
    >>> round(2.5)
    2
    poet00
    poet00
    Jul 22, 2019
    14
    `round(Decimal("0.123456789"), 3) + Decimal("0.01") #Decimal('0.133')`

    ```
    from decimal import *

    getcontext().prec

    ```

    不是 decimal 的坑, 初始化 decimal 变量,推荐使用 string 或者在运算时手动指定 percesion
    1iuh
    1iuh
    Jul 22, 2019
    15
    初始化 decimal 别传浮点数进去
    1iuh
    1iuh
    Jul 22, 2019
    16
    另外 decimal 有自己 round 方法。
    hjq98765
    hjq98765
    Jul 22, 2019
    17
    @djj510620510 #12 原文:“@hjq98765 应该 JS 才会出现吧 /doge ”
    ======
    回复:python3 也有这个坑,刚从 python2 转过来的时候着实被坑了一把
    azh7138m
    azh7138m
    Jul 22, 2019
    18
    @djj510620510
    > 四舍六入五成双

    C++ 也会
    yushi17
    yushi17
    Jul 22, 2019 via Android
    19
    5oiR5piv5YK76YC8
    5oiR5piv5YK76YC8
    Jul 23, 2019
    20
    因为你传进去的时候就不是精确的
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   923 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 48ms · UTC 21:08 · PVG 05:08 · LAX 13:08 · JFK 16:08
    ♥ Do have faith in what you're doing.