programacion - Biblioteca de alta precisión de punto flotante de Java
punto flotante plc (4)
¿Qué bibliotecas para Java existen que tengan una implementación rápida para operaciones de coma flotante o punto fijo con una precisión de varios miles de dígitos? ¿Qué tan efectivos son?
Un requisito para mí es que implementa un algoritmo de multiplicación que es mejor que el algoritmo de multiplicación ingenuo que toma 4 veces más tiempo para un número de dígitos 2 veces mayor (compare los algoritmos de multiplicación ).
¿Has comprobado el rendimiento de BigDecimal ? No puedo ver nada obvio en el JavaDoc, pero sin duda sería mi primer puerto de escala.
Apfloat ofrece una alta precisión en la mantisa, pero parece dar una precisión menor a la habitual en el exponente (basado en el hecho de que se bloquea con "Logaritmo de cero" para valores que el doble puede manejar). Entonces no es útil para grandes números.
Además, la documentación dice:
"Existe una dificultad con los constructores Apfloat (flotante, largo) y Apfloat (doble, largo). Como los flotantes y los dobles siempre se representan internamente en radix 2, la conversión a cualquier otra raíz generalmente causa errores de redondeo, y el apfloat resultante no será preciso para la cantidad deseada de dígitos.
Por ejemplo, 0.3 no se puede presentar exactamente en la base 2. Cuando construyes un apfloat como el nuevo Apfloat (0.3f, 1000), el número resultante no tendrá una precisión de 1000 dígitos, sino solo hasta aproximadamente 7 dígitos (en raíz 10). De hecho, el número resultante será algo así como 0.30000001192092896 ... "
Esto parece hacer que Apfloat sea mínimamente útil.
BigDecimal no tiene una función de logaritmo, y la documentación no dice si le permite hacer números más grandes que un doble; el exponente es de 32 bits, más o menos.
Hay tres bibliotecas mencionadas en la página Aritmética de Precisión Arbitraria : java.math (que contiene el mencionado BigDecimal), Apfloat y JScience . Corro un poco de control de velocidad en ellos, que solo usa suma y multiplicación.
El resultado es que, para un número relativamente pequeño de dígitos, BigDecimal está bien (la mitad de rápido que los demás para 1000 dígitos), pero si usa más dígitos está muy lejos - JScience es aproximadamente 4 veces más rápido. Pero el claro ganador del rendimiento es Apfloat. Las otras bibliotecas parecen usar algoritmos de multiplicación ingenuos que toman tiempo proporcional al cuadrado de la cantidad de dígitos, pero el tiempo de Apfloat parece crecer casi linealmente. En 10000 dígitos era 4 veces más rápido que JScience, pero en 40000 dígitos es 16 veces más rápido que JScience.
Por otro lado: JScience ofrece una EXCELENTE funcionalidad para problemas matemáticos: matrices, vectores, algoritmos simbólicos, solución de sistemas de ecuaciones y otras cosas. Así que probablemente iré con JScience y luego escribiré un wrapper para integrar Apfloat en los algoritmos de JScience, debido al buen diseño esto parece fácilmente posible.
(ACTUALIZACIÓN: Escribí un paquete de prueba para el paquete de números de JScience y solucioné varios errores. Esto entró en la versión 4.3.1. Por lo tanto, puedo recomendar revisarlo).