Eli*_*Eli 10 python memory floating-point precision decimal
我正在使用Decimal类进行需要精度的操作.
我想使用'尽可能大'的精度.有了这个,我的意思是程序运行的系统可以处理的精确.
要设置一定的精度,这很简单:
import decimal
decimal.getcontext().prec = 123 #123 decimal precision
Run Code Online (Sandbox Code Playgroud)
我试图找出'Decimal'类可以计算的最大精度:
print(decimal.MAX_PREC)
>> 999999999999999999
Run Code Online (Sandbox Code Playgroud)
所以我试着将精度设置为最大精度(知道它可能不起作用..):
decimal.getcontext().prec = decimal.MAX_PREC
Run Code Online (Sandbox Code Playgroud)
但是,当然,这会引发内存错误(在部门上)
所以我的问题是:我如何计算当前系统可以处理的最大精度?
额外信息:
import sys
print(sys.maxsize)
>> 9223372036854775807
Run Code Online (Sandbox Code Playgroud)
试图这样做是一个错误.在一个问题上投入更多精确度对于新手来说是一个诱人的陷阱,但它并没有那么有用,特别是对于这个极端.
即使这是一个明确定义的概念,您的操作实际上也不需要"尽可能大"的精度.要么他们需要精确的算术,在这种情况下decimal.Decimal
完全是错误的工具,你应该看看类似fractions.Fraction
或符号计算,或者他们不需要那么多精度,你应该确定你实际需要多少精度并使用它.
如果您仍然想要在问题上抛出所有精度,那么实际精确度将取决于您正在做什么样的数学计算,以及您尝试在内存中存储多少非常精确的数字.这可以通过分析程序和Decimal
对象的内存要求来确定,或者您可以将精度作为参数和二进制搜索,以获得不会导致崩溃的最大精度.
我想推荐一个函数,它允许您以蛮力的方式估计给定操作的最大精度:
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
Run Code Online (Sandbox Code Playgroud)
这只是一次将间隔减半,并查看是否发生错误。调用max_iter=10
并a=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
Run Code Online (Sandbox Code Playgroud)
这可能会让您大致了解您正在处理的内容。这在 i5-3470 和 16GB RAM 上花费了大约半小时,所以你真的只会将它用于测试目的。
我不认为有一种实际的确切方法可以为您的操作获得最大精度,因为您必须准确了解内存使用对内存消耗的依赖性。我希望这至少对你有所帮助,我真的很想知道,你需要那种精度。
编辑我觉得这真的需要添加,因为我在这里最受好评的帖子下阅读了您的评论。以这种方式使用任意高精度不是人们计算常数的方式。你会编程一些东西,以聪明的方式利用磁盘空间(例如计算 RAM 中的一堆数字并将这些数字写入文本文件),但永远不要只使用 RAM/swap,因为这总是会限制你的结果。使用现代算法来计算 pi,您不需要无限的 RAM,您只需在机器中放置另一个 4TB 硬盘驱动器并让它写入下一个数字。到目前为止,对于数学常数。
现在对于物理常数:它们并不精确。他们依赖于测量。我不太确定 atm(会编辑),但我认为最准确的物理常数有 10**(-8) 的误差。提高它的精度,并不会使它更精确,您只是计算出更多错误的数字。
不过,作为一个实验,这是一个有趣的想法,这就是我什至首先发布答案的原因。
从您上面的回复来看:
\n\n\n\n\n如果我只想在 pi 中查找比已找到的数字更多的数字怎么办?如果我想测试 e 或 mill 常数的无理性该怎么办?
\n
我得到它。我真的这么做。我的一个 SO 问题已经有好几年了,是关于 Python 的任意精度浮点库的。如果这些是您想要生成的数字表示类型,请为深入研究做好准备。十进制/FP 算术在计算机科学中是出了名的棘手。
\n\n\n\n\n有些程序员在遇到问题时会想 \xe2\x80\x9c我知道,我\xe2\x80\x99会使用浮点运算。 \xe2\x80\x9d 现在他们有 1.999999999997 个问题。\xe2\x80\x93 @tomscott
\n
我认为当其他人说想知道给定平台上 Python Decimal 类型的最大精度是多少是一个“错误”或“这取决于”时,他们比我猜测的更字面地理解你的问题这是有意的。您询问了 Python Decimal 类型,但如果您对出于教育目的的 FP 算术感兴趣(“在 pi 中查找更多数字”),您将需要比 Decimal 或float更强大、更灵活的工具。这些内置的 Python 类型根本无法与之相提并论。这些对于 NASA 来说也许已经足够好了,但它们有局限性……事实上,正是你所问的局限性。
\n\n这就是多精度(或任意精度)浮点库的用途:任意精确的表示。想计算未来 20 年的圆周率吗?Python 的 Decimal 类型甚至无法让你度过这一天。
\n\n事实上,多精度二进制浮点运算仍然是一种边缘科学。对于 Python,您需要在 Linux 机器上安装GNU MPFR库,然后您可以使用 Python 库gmpy2进行深入研究。
\n\n那么,问题不是“我的程序可以使用的最大精度是多少?”
\n\n它是,“我如何编写我的程序,使其能够运行到停电为止?”
\n\n这是一个完全不同的问题,但至少它受到你的算法的限制,而不是它运行的硬件。
\n