如何获得最大的精度? (Python-十进制)

时间:2018-12-06 21:37:05

标签: python memory floating-point decimal precision

我将Decimal类用于需要精确度的操作。

我想使用“最大可能”的精度。有了这个,我的意思是程序运行所在的系统可以处理的精确度。

要设置一定的精度很简单:

import decimal
decimal.getcontext().prec = 123 #123 decimal precision

我试图弄清楚“十进制”类可以计算的最大精度:

print(decimal.MAX_PREC)
>> 999999999999999999

因此,我尝试将精度设置为最大精度(知道它可能无法工作..):

decimal.getcontext().prec = decimal.MAX_PREC

但是,当然,这会引发内存错误(除法运算)

所以我的问题是:如何找出当前系统可以处理的最大精度?

其他信息:

import sys
print(sys.maxsize)
>> 9223372036854775807

4 个答案:

答案 0 :(得分:9)

尝试执行此操作是一个错误。在一个问题上提高精度是吸引新手浮点运算的诱人陷阱,但它没有什么用处,特别是在这种极端情况下。

您的操作实际上并不需要“最大可能”的精度,即使这是一个定义明确的概念。他们要么需要精确的算术,在这种情况下,decimal.Decimal完全是错误的工具,您应该研究fractions.Fraction之类的东西或符号计算,或者它们不需要那么多精度,您应该确定实际需要多少精度并使用该精度。

如果您仍然想解决所有可能的精度问题,那么到底有多少精度取决于您正在执行的数学类型以及要存储在其中的多少个荒谬的精确数字一次记忆。这可以通过分析程序和Decimal对象的内存需求来确定,或者可以将精度作为参数并通过二进制搜索来寻找不会导致崩溃的最大精度。

答案 1 :(得分:4)

我想建议一个函数,允许您以蛮力方式估计给定操作的最大精度:

def find_optimum(a,b, max_iter):
    for i in range(max_iter):
        print(i)
        c = int((a+b)/2)
        decimal.getcontext().prec = c
        try:
            dummy = decimal.Decimal(1)/decimal.Decimal(7) #your operation
            a = c
            print("no fail")
        except MemoryError:
            print("fail")
            dummy = 1
            b = c
        print(c)
        del dummy

这只是一次将间隔减半,并查看是否发生错误。用max_iter=10a=int(1e9), b=int(1e11)进行调用会得到:

>>> find_optimum(int(1e9), int(1e11), 10)
0
fail
50500000000
1
no fail
25750000000
2
no fail
38125000000
3
no fail
44312500000
4
fail
47406250000
5
fail
45859375000
6
no fail
45085937500
7
no fail
45472656250
8
no fail
45666015625
9
no fail
45762695312

这可能使您大致了解要处理的内容。 i5-3470和16GB RAM大约花费了半小时,因此您实际上只能将其用于测试目的。

我不认为,有一种实际的精确方法可以使您的操作获得最大的精度,因为您必须确切了解内存使用情况对内存消耗的依赖性。我希望这至少对您有所帮助,我真的很想知道,您需要那种精度。

编辑,我觉得确实需要添加此内容,因为我在此处阅读了评分最高的帖子下的评论。以这种方式使用任意高精度并不是人们计算常数的方式。您将编写一些程序,以一种聪明的方式利用磁盘空间(例如,在RAM中计算一堆数字并将其写入文本文件),但绝不要仅使用RAM /交换,因为这总是会限制您的结果。使用现代算法来计算pi,您不需要无限的RAM,您只需在计算机中放置另一个4TB硬盘驱动器,然后让它写入下一位数字即可。到目前为止,对于数学常数。

现在是物理常数:它们不精确。他们依靠测量。我不太确定atm(会进行编辑),但我认为最精确的物理常数的误差为10 **(-8)。赋予它更高的精度,并不能使其更加精确,您只需计算更多错误的数字即可。

不过,作为一个实验,这是一个有趣的主意,这就是为什么我什至首先发布答案的原因。

答案 2 :(得分:2)

Decimal类的最大精度取决于设备上的内存,因此对于一般情况,没有好的方法来设置它。基本上,您是将计算机上的所有内存分配给一个变量以获得最大的精度。

如果数学运算支持它,则长整数将为您提供无限的精度。但是,您只能使用整数。

加,减,乘和简单指数可以完全用长整数执行。

在Python 3之前,内置的long数据类型将执行任意精度计算。 https://docs.python.org/2/library/functions.html#long

在Python> = 3中,int数据类型现在表示长整数。 https://docs.python.org/3/library/functions.html#int

一种实现64位整数数学的示例是bitcoind,其中事务计算需要精确的值。但是,比特币交易的精度限于1个“ Satoshi”;每个比特币都定义为10 ^ 8(整数)Satoshi。

Decimal类在后台运行类似。十进制精度10 ^ -8类似于比特币-聪子范例。

答案 3 :(得分:0)

从上面的回复中

  

如果我只想在pi中找到比已经找到的数字多的数字怎么办?如果我想测试e或mill常数的不合理性该怎么办?

我明白了。我是真的我的one SO question已有数年历史,它是关于Python的任意精度浮点库的。如果这些是您要生成的数字表示形式,请为深入研究做好准备。小数/ FP算术是计算机科学中的notoriously tricky

  

一些程序员遇到问题时,会想:“我知道,我将使用浮点算法。”现在,他们遇到了1.999999999997问题。 – @tomscott

我认为,当其他人说这是一个“错误”或“取决于”时,想知道给定平台上的Python Decimal类型的最大精度是多少,他们比我猜想的更多地是您的问题。原本打算。您询问了Python十进制类型,但是如果您出于教育目的对FP算术感兴趣-“要在pi中找到更多数字”-您将需要比Decimal更强大,更灵活的工具或float。这些内置的Python类型甚至都没有 close 出现。这些对于NASA也许足够好,但是它们有局限性……实际上,您所要求的是极限。

这就是多精度(或arbitrary-precision)浮点库的用途:任意精确的表示形式。是否想计算未来20年的 pi ? Python的Decimal类型甚至都不会让您度过 day

事实是,多精度二进制FP算法仍然是一种边缘科学。对于Python,您需要在Linux机器上安装GNU MPFR库,然后可以使用Python库gmpy2进行任意深度的挖掘。

然后,问题不是,“我的程序可以使用的最大精度是多少?”

是,“我如何编写程序,以便程序可以运行直到断电?”

那是另外一个问题,但至少受您的算法限制,而不是它所运行的硬件限制。