如果您有一个函数返回 的子类,c_longdouble
它将返回 ctypes 包装的字段对象,而不是转换为 python float
。然后,您可以从中提取字节(memcpy
例如,使用 c_char 数组)或将对象传递给另一个 C 函数以进行进一步处理。该snprintf
函数可以将其格式化为字符串,以便打印或转换为高精度python数字类型。
import ctypes
libc = ctypes.cdll['libc.so.6']
libm = ctypes.cdll['libm.so.6']
class my_longdouble(ctypes.c_longdouble):
def __str__(self):
size = 100
buf = (ctypes.c_char * size)()
libc.snprintf(buf, size, '%.35Le', self)
return buf[:].rstrip('\0')
powl = libm.powl
powl.restype = my_longdouble
powl.argtypes = [ctypes.c_longdouble, ctypes.c_longdouble]
for i in range(1020,1030):
res = powl(2,i)
print '2**'+str(i), '=', str(res)
输出:
2**1020 = 1.12355820928894744233081574424314046e+307
2**1021 = 2.24711641857789488466163148848628092e+307
2**1022 = 4.49423283715578976932326297697256183e+307
2**1023 = 8.98846567431157953864652595394512367e+307
2**1024 = 1.79769313486231590772930519078902473e+308
2**1025 = 3.59538626972463181545861038157804947e+308
2**1026 = 7.19077253944926363091722076315609893e+308
2**1027 = 1.43815450788985272618344415263121979e+309
2**1028 = 2.87630901577970545236688830526243957e+309
2**1029 = 5.75261803155941090473377661052487915e+309
(请注意,我对 35 位精度的估计结果对于long double
英特尔处理器上的计算过于乐观,因为英特尔处理器只有 64 位尾数。如果您打算转换为%a
不基于十进制表示。)%e
f
g