我一直在使用一些使用Python的mpmath
库进行高精度计算的函数。但是,现在我需要将mpmath
格式的mpf
计算结果转换为numpy
的{{1}}(当然,精度/数字的损失)。
如果要转换的数字所需的位数少于Python double所能处理的位数,则显而易见的转换有效:
longdouble
提供输出:
x = mp.mpmathify("1e-300")
float(x)
np.longdouble(x)
现在,如果要转换的数字需要的位数比标准Python double所能处理的更多,但少于系统的long double所能处理的位数,则可以预期In [1]: x = mp.mpmathify("1e-300")
In [2]: float(x)
Out[2]: 1e-300
In [3]: np.longdouble(x)
Out[3]: 1.00000000000000002506e-300
将返回零,但是float(x)
将存储np.longdouble(x)
对象的实际转换版本。但是,这不会发生:
mpf
如果使用In [4]: x = mp.mpmathify("1e-3000")
In [5]: x
Out[5]: mpf('1.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e-3000')
In [6]: float(x)
Out[6]: 0.0
In [7]: np.longdouble(x)
Out[7]: 0.0
而不是np.float128(x)
,也会发生同样的情况。另外,如果我尝试将np.longdouble(x)
值存储在long double类型的numpy数组中,也会发生同样的情况:
mpf
我的问题:
(1)为什么会这样?我的印象是,当我们告诉numpy转换为long double或float128时,它首先转换为double或float64,从而失去了精确度-然后破坏了目标。
(2)我该如何做以上打算,即将In [8]: arr = np.empty((1, 1), dtype=np.longdouble)
In [9]: arr[0, 0] = x
In [10]: arr[0, 0]
Out[10]: 0.0
生成的数字转换为numpy长的double或float128,而当该数字适合一个整数时不折叠为零。长双倍还是float128?
如果您想知道,这是我系统中最低的正长双倍数:
mpmath