zoukankan      html  css  js  c++  java
  • 一个关于浮点数运算需要注意的地方

    1 a = 4.2
    2 b = 2.1
    3 
    4 a + b
    5 
    6 (a + b) == 6.3 

      浮点数存在的一个问题,不能精确的表示十进制数。这是由于底层 CPU 和  IEEE 754 标准通过自己的浮点单位去执行算术时的特征。看似有穷的小数, 在计算机的二进制表示里却是无穷的。其实这不是Python的问题,而是实数的无限精度跟计算机的有限内存之间的矛盾。

      举个例子,假如说我只能使用整数(即只精确到个位,计算机内的浮点数也只有有限精度,以C语言中的双精度浮点数double为例,精度为52个二进制位),要表示任意实数(无限精度)的时候我就只能通过舍入(rounding)来近似表示。

      比如1.2我会表示成1,2.4表示成2,3.6表示成4.

      所以呢?

      在算1.2 - 1.2的时候,由于计算机表示的问题,我算的实际上是1 - 1,结果是0,碰巧蒙对了;

      在算1.2 + 1.2 - 2.4的时候,由于计算机表示的问题,我算的实际上是1 + 1 - 2,结果是0,再次蒙对了;

      但是在算1.2 + 1.2 + 1.2 - 3.6的时候,由于计算机表示的问题,我算的实际上是1 + 1 + 1 - 4,结果是-1,运气没那么好啦!

      这里的1.2, 2.4, 3.6就相当于你问题里的0.1, 0.2和0.3,1, 2, 4则是真正在计算机内部进行运算的数值,我说清楚了吗?

      另:不仅仅是浮点数的在计算机内部的表示有误差,运算本身也可能会有误差。比如整数2可以在计算机内准确表示,但是要算根号2就有误差了;再比如两个浮点数相除,本来两个数都是精确表示的,但除的结果精度却超出了计算机内实数的表示范围,然后就有误差了。

      一般情况下,这一点点的小误差是允许存在的。如果不能容忍这种误差(比如金融领域),那么就要考虑用一些途径来解决这个问题了。

      使用Decimal模块就可以解决这个问题。

    1 from decimal import Decimal
    2 a = Decimal('4.2')
    3 b = Decimal('2.1')
    4 a + b
    5 
    6 print(a + b)
    7 
    8 (a + b) == Decimal('6.3')

      

      尽管代码看起来比较奇怪,使用字符串来表示数字,但是 Decimal 支持所有常用的数学运算。总的来说,当涉及金融领域时,哪怕是一点小小的误差在计算过程中都是不允许的。因此 decimal 模块为解决这类问题提供了方法。

    作者:俊豪郎
    出处:http://www.cnblogs.com/shaohan/
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。
  • 相关阅读:
    UWP 统一平台开发介绍
    异步编程之Javascript Promises 规范介绍
    Winform文件下载之WebClient
    微软 Build 2016年开发者大会发布多项功能升级
    绝对干货:自定义msi安装包的执行过程
    人机大战之AlphaGo的硬件配置和算法研究
    .Net 高效开发之不可错过的实用工具
    ComponentOne 2016 年产品规划
    三天学会HTML5 ——多媒体元素的使用
    三天学会HTML5——SVG和Canvas的使用
  • 原文地址:https://www.cnblogs.com/shaohan/p/9085750.html
Copyright © 2011-2022 走看看