Python如何执行精确的浮点数运算

问题

你需要对浮点数执行精确的计算操作,并且不希望有任何小误差的出现。

解决方案

浮点数的一个普遍问题是它们并不能精确的表示十进制数。 并且,即使是最简单的数学运算也会产生小的误差,比如:

>>> a = 4.2
>>> b = 2.1
>>> a + b
6.300000000000001
>>> (a + b) == 6.3
False
>>>

这些错误是由底层CPU和IEEE 754标准通过自己的浮点单位去执行算术时的特征。 由于Python的浮点数据类型使用底层表示存储数据,因此你没办法去避免这样的误差。

如果你想更加精确(并能容忍一定的性能损耗),你可以使用 decimal 模块:

>>> from decimal import Decimal
>>> a = Decimal('4.2')
>>> b = Decimal('2.1')
>>> a + b
Decimal('6.3')
>>> print(a + b)
6.3
>>> (a + b) == Decimal('6.3')
True

初看起来,上面的代码好像有点奇怪,比如我们用字符串来表示数字。 然而, Decimal 对象会像普通浮点数一样的工作(支持所有的常用数学运算)。 如果你打印它们或者在字符串格式化函数中使用它们,看起来跟普通数字没什么两样。

decimal 模块的一个主要特征是允许你控制计算的每一方面,包括数字位数和四舍五入运算。 为了这样做,你先得创建一个本地上下文并更改它的设置,比如:

>>> from decimal import localcontext
>>> a = Decimal('1.3')
>>> b = Decimal('1.7')
>>> print(a / b)
0.7647058823529411764705882353
>>> with localcontext() as ctx:
...   ctx.prec = 3
...   print(a / b)
...
0.765
>>> with localcontext() as ctx:
...   ctx.prec = 50
...   print(a / b)
...
0.76470588235294117647058823529411764705882352941176
>>>

讨论

decimal 模块实现了IBM的”通用小数运算规范”。不用说,有很多的配置选项这本书没有提到。

Python新手会倾向于使用 decimal 模块来处理浮点数的精确运算。 然而,先理解你的应用程序目的是非常重要的。 如果你是在做科学计算或工程领域的计算、电脑绘图,或者是科学领域的大多数运算, 那么使用普通的浮点类型是比较普遍的做法。 其中一个原因是,在真实世界中很少会要求精确到普通浮点数能提供的17位精度。 因此,计算过程中的那么一点点的误差是被允许的。 第二点就是,原生的浮点数计算要快的多-有时候你在执行大量运算的时候速度也是非常重要的。

即便如此,你却不能完全忽略误差。数学家花了大量时间去研究各类算法,有些处理误差会比其他方法更好。 你也得注意下减法删除以及大数和小数的加分运算所带来的影响。比如:

>>> nums = [1.23e+18, 1, -1.23e+18]
>>> sum(nums) # Notice how 1 disappears
0.0
>>>

上面的错误可以利用 math.fsum() 所提供的更精确计算能力来解决:

>>> import math
>>> math.fsum(nums)
1.0
>>>

然而,对于其他的算法,你应该仔细研究它并理解它的误差产生来源。

总的来说, decimal 模块主要用在涉及到金融的领域。 在这类程序中,哪怕是一点小小的误差在计算过程中蔓延都是不允许的。 因此, decimal 模块为解决这类问题提供了方法。 当Python和数据库打交道的时候也通常会遇到 Decimal 对象,并且,通常也是在处理金融数据的时候。

以上就是Python如何执行精确的浮点数运算的详细内容,更多关于Python执行精确的浮点数运算的资料请关注我们其它相关文章!

(0)

相关推荐

  • Python双精度浮点数运算并分行显示操作示例

    本文实例讲述了Python双精度浮点数运算并分行显示操作.分享给大家供大家参考,具体如下: #coding=utf8 def doubleType(): ''''' Python中的浮点数是双精度浮点数,可以用十进制或科学计数法表示. 实际精度依赖于机器架构和创建Python解释器的编译器. 浮点数值通常都有一个小数点和一个可选的后缀e(大写或小写,表示科学计数法). 在e和指数之间可以用正(+)或负(-)表示指数的正负(正数可以省略符号) ''' (one,two,three,four,fiv

  • python中实现精确的浮点数运算详解

    为什么说浮点数缺乏精确性? 在开始本文之前,让我们先来谈谈浮点数为什么缺乏精确性的问题,其实这不是Python的问题,而是实数的无限精度跟计算机的有限内存之间的矛盾. 举个例子,假如说我只能使用整数(即只精确到个位,计算机内的浮点数也只有有限精度,以C语言中的双精度浮点数double为例,精度为52个二进制位),要表示任意实数(无限精度)的时候我就只能通过舍入(rounding)来近似表示. 比如1.2我会表示成1,2.4表示成2,3.6表示成4. 所以呢? 在算1.2 - 1.2的时候,由于计

  • Python中的浮点数原理与运算分析

    本文实例讲述了Python中的浮点数原理与运算.分享给大家供大家参考,具体如下: 先看一个违反直觉的例子: >>> s = 0. >>> for i in range(10): s += .1 >>> s 0.9999999999999999 # 错误被累加 再看一个更为普遍,直接影响判断逻辑的例子: >>> from math import sqrt >>> a = sqrt(2) >>> a*a

  • Python如何执行精确的浮点数运算

    问题 你需要对浮点数执行精确的计算操作,并且不希望有任何小误差的出现. 解决方案 浮点数的一个普遍问题是它们并不能精确的表示十进制数. 并且,即使是最简单的数学运算也会产生小的误差,比如: >>> a = 4.2 >>> b = 2.1 >>> a + b 6.300000000000001 >>> (a + b) == 6.3 False >>> 这些错误是由底层CPU和IEEE 754标准通过自己的浮点单位去执行

  • 聊聊Python中的浮点数运算不准确问题

    大家好,老 Amy 来了.之前就意识到一个问题,但是最近又有朋友提出来了,所以就想着干脆记录下来,分享给大家叭~ 啥问题呢?请看题: 也就是说,需要大家计算1.1-1的值,很多朋友会说:"emmm-这还不简单,玩我呢?不就是0.1嘛" 但是如果你用 python 去执行一下,会发现结果跟你想的不太一样,如下图: 这样大家是不是发现了什么问题?是的,浮点数在运算过程中并没有保证完全精确,是什么原因导致了这种现象呢?很多朋友就会窃喜:"这不就是 Python 的 bug 嘛~&q

  • python执行精确的小数计算方法

    在进行浮点数计算时它们无法精确表达出所有的十进制小数位. a = 4.1 b = 5.329 print(a+b) 9.428999999999998 这些误差实际上是底层CPU的浮点运算单元和IEEE754浮点数算数标准的一种"特性".python的浮点数类型保存的数据采用的是原始表示形式,因此使用float实例时就不能避免这样的误差. 我们可以使用decimal模块避免这种操作(如果不介意牺牲下性能): from decimal import Decimal a = Decimal

  • JS浮点数运算结果不精确的Bug解决

    前言 最近在做项目的时候,涉及到产品价格的计算,经常会出现JS浮点数精度问题,这个问题,对于财务管理系统的开发者来说,是个非常严重的问题(涉及到钱相关的问题都是严重的问题),这里把相关的原因和问题的解决方案整理一下,也希望给各位提供一些参考. 一. 常见例子   // 加法 0.1 + 0.2 = 0.30000000000000004 0.1 + 0.7 = 0.7999999999999999 0.2 + 0.4 = 0.6000000000000001 // 减法 0.3 - 0.2 =

  • JavaScript 浮点数运算 精度问题

    Js代码 复制代码 代码如下: <script type="text/javascript" language="javascript"> alert(1/3);//弹出: 0.3333333333333333 alert(0.09999999 + 0.00000001);//弹出: 0.09999999999999999 alert(-0.09999999 - 0.00000001);//弹出: -0.09999999999999999 alert(0

  • Python闭包执行时值的传递方式实例分析

    本文实例分析了Python闭包执行时值的传递方式.分享给大家供大家参考,具体如下: 代码中有问题和问题的解释. #!/usr/bin/python #coding: utf-8 # 判断一个人是否及格,如果满分150,则90及格,如果满分100,则60及格 # 开始的疑惑:当fun函数执行完以后,对应的val的值就应该消失,但是, # 当下面代码再次调用f(60)的时候(这个f()函数就是fun_c()函数) # 却能够打印出val的值??? def fun(val): 'val是得到的分数'

  • 详解JavaScript 浮点数运算的精度问题

    问题描述 在 JavaScript 中整数和浮点数都属于 Number 数据类型,所有数字都是以 64 位浮点数形式储存,即便整数也是如此. 所以我们在打印 1.00 这样的浮点数的结果是 1 而非 1.00 .在一些特殊的数值表示中,例如金额,这样看上去有点变扭,但是至少值是正确了.然而要命的是,当浮点数做数学运算的时候,你经常会发现一些问题,举几个例子: // 加法 ===================== // 0.1 + 0.2 = 0.30000000000000004 // 0.7

  • 关于Python中定制类的比较运算实例

    Python中的比较运算有几种:小于.小于等于.等于.大于等于.大于.不等于等.如果我们的数据对象具有明确的物理含义,比如说数值是带有数字与物理单位的字符串组合,那么进行大小比较的时候就可以做此定制. 下面针对6种比较方法中的一种来进行定制示范,选择小于判断来做尝试. 写如下示范代码: class myClass: def __init__(self,value): self.value = value def __lt__(self,other): return int(self.value[

随机推荐