Nếu bạn có hàm trả về lớp con của c_longdouble
, nó sẽ trả về đối tượng trường bao bọc ctypes thay vì chuyển đổi thành trăn float
. Sau đó, bạn có thể trích xuất các byte từ này (ví dụ: memcpy
thành một mảng c_char) hoặc chuyển đối tượng sang một hàm C khác để xử lý tiếp. Hàm snprintf
có thể định dạng nó thành một chuỗi để in hoặc chuyển đổi thành một kiểu số python có độ chính xác cao.
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)
Output:
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
(Lưu ý rằng ước tính của tôi là 35 chữ số chính xác hóa ra là quá lạc quan cho long double
tính toán trên bộ xử lý Intel, trong đó chỉ có 64 bit của mantissa Bạn nên sử dụng. %a
thay vì %e
/f
/g
nếu bạn có ý định chuyển đổi sang định dạng không dựa trên đại diện thập phân.)
Tôi muốn làm điều gì đó tương tự và đăng câu hỏi [ở đây] (http://stackoverflow.com/questions/25380004/how-do-i-force-usage-of-long-doubles-with-cython), và bây giờ nhận ra rằng tôi về cơ bản cùng một vấn đề bạn đã làm. @Autoplectic, tôi có thể biết những gì bạn cuối cùng đã làm? – Abhinav