zoukankan      html  css  js  c++  java
  • python 浮点数四舍六入五成双

    问题
    a = 0.215
    b = 0.225
    print round(a, 2)
    print round(b, 2)
    
    # 执行结果
    0.21
    0.23
    
    • 0.215 在进行四舍五入时,保留的两位小数没有进1
    • 0.225 在进行四舍五入时,保留的两位小数可以进1
    原因
    • 因为在 Python3 里面,round 对小数的精确度采用了 四舍六入五成双 的方式。

    • 例如对于一个浮点数 a.bcd,需要精确到小数点后两位,那么就要看小数点后第三位:

      • 如果 d 小于 5,直接舍去;
      • 如果 d 大于 5,直接进位;
      • 如果 d 等于 5:
        • d 后面没有数据,且 c 为偶数,那么不进位,保留 c
        • d 后面没有数据,且 c 为奇数,那么进位,c 变成 (c + 1)
      • 如果 d 后面还有非 0 数字,例如实际上小数为 a.bcdef,此时一定要进位,c 变成 (c + 1)
    • 所以,round 给出的结果如果跟设想的不一样,那么需要考虑两个原因:

      • 你的这个小数在计算机中能不能被精确储存?如果不能,那么它可能并没有达到四舍五入的标准,例如 1.115,它的小数点后第三位实际上是 4,当然会被舍去
      • 如果你的这个小数在计算机中能被精确表示,那么,round 采用的进位机制是奇进偶舍,所以这取决于你要保留的那一位,它是奇数还是偶数,以及它的下一位后面还有没有数据
    解决四舍五入精度问题
    #!/usr/bin/python
    # -*- encoding: utf-8 -*-
    from decimal import Decimal
    import decimal
    
    # 四舍五入,保留2位小数
    def setDecimal(data, dec_place='0.00'):
        return Decimal(data).quantize(Decimal(dec_place), rounding=decimal.ROUND_HALF_UP)
    
    a = '0.215'
    b = '0.225'
    
    print round(setDecimal(a), 2)
    print round(setDecimal(b), 2)
    
    # 输出结果
    0.22
    0.23
    
    • 注意:decimal 接收的参数必须是字符串,不能是浮点数;如果是浮点数结果依然不准确
    • 如果你传入的参数为浮点数,并且这个浮点值在计算机里面不能被精确存储,那么它会先被转换为一个不精确的二进制值,然后再把这个不精确的二进制值转换为等效的十进制值
    • 对于不能精确表示的小数,当你传入的时候,Python 在拿到这个数前,这个数就已经被转成了一个不精确的数了。所以虽然参数传入的是 11.245,但是 Python 拿到的实际上是 11.24499999999
  • 相关阅读:
    shmget() 建立共享内存
    [转]SQL2005 连接问题处理
    [转]工作以后十不要,自勉
    C#学习笔记
    一位软件工程师6年总结(转)
    时间相关处理
    Litter Tips
    [转] VS打开解决方案时报错的处理方法
    面向对象—设计模式
    SQL Server 2000中的错误
  • 原文地址:https://www.cnblogs.com/gxfaxe/p/14970856.html
Copyright © 2011-2022 走看看