Aritmética de alta precisión en Python y / o C / C ++?

Resumen: ¿Qué paquete de Python o C-Library es la mejor opción para operaciones aritméticas de muy alta precisión?

Tengo algunas funciones que convierten los días fraccionarios ( 0.0-0.99999.. ) a un formato legible por el ser humano (horas, minutos, segundos, pero lo más importante: milisegundos, microsegundos, nanosegundos).

La conversión se realiza mediante estas funciones: (tenga en cuenta que todavía no he implementado la corrección de la zona horaria)

 d = lambda x: decimal.Decimal(str(x)) cdef object fractional2hms(double fractional, double timezone): cdef object total, hms, ms_mult cdef int i hms = [0,0,0,0,0,0] ms_mult = (d(3600000000000), d(60000000000), d(1000000000), d(1000000), d(1000), d(1)) # hms = [0,0,0,0,0] total = d(fractional) * d(86400000000000) for i in range(len(ms_mult)): hms[i] = (total - (total % ms_mult[i])) / ms_mult[i] total = d(total % ms_mult[i]) return ([int(x) for x in hms]) 

Y a fraccional:

 def to_fractional(self): output = (self.hour / d(24.0)) + (self.minute / d(1440.0)) output += (self.second / d(86400.0)) + (self.millisecond / d(86400000.0)) output += self.microsecond / d(86400000000.0) output += self.nanosecond * (d(8.64) * d(10)**d(-9)) return output 

Mis resultados de una conversión de ida y vuelta son inexactos, sin embargo:

 jdatetime.DayTime.fromfractional(d(0.567784356873)).to_fractional() Decimal('0.56779150214342592592592592592592592592592592592592592592592592592592592592592592592592592592592592592592592592592') # Difference in-out: Decimal('0.000007145270') 

Cuando cambio d() para devolver un flotador Python normal:

 # Difference in-out: 7.1452704258900823e-06 (same) 

Por lo tanto, mi pregunta es: ¿Qué paquete de Python o biblioteca C puede hacer esto con mayor precisión?

La diferencia se debe a un error en su código, no a un problema de precisión. La línea

 output += self.nanosecond * (d(8.64) * d(10)**d(-9)) 

debería ser algo como

 output += self.nanosecond / d(86400000000000) 

Además, es una mala idea usar literales de punto flotante en su código y convertirlos a Decimal . Esto primero redondeará el número literal a la precisión de punto flotante. La conversión posterior a Decimal no puede restaurar la precisión perdida. Tratar

 d = decimal.Decimal 

y use solo literales enteros (solo quite la parte .0 ).

CTRL-F “Bibliotecas” allí: aritmética de precisión arbitraria

EDITAR: Extraer de las bibliotecas de enlaces solo para c ++ y python (y eliminar algunas, que no tienen números flotantes, sino solo números enteros)

python

1) mpmath


c ++

1) flotar

2) clase base de un número

3) Bigfloat

4) lidia

5) mapm

6) MIRACL

7) NTL

8) ttmath