2010-10-04 17 views
13

En uno de mis módulos, tengo que lidiar con el concepto de infinito. Hasta la fecha, he estado usando 9**9**9 como infinito positivo, y esto parece funcionar bien, es rápido, y parece ser lo que los internos de Perl usan como infinito.¿Cuál es la mejor manera de verificar el infinito en un módulo Perl?

Sin embargo, las cosas se ponen un poco incierto si un usuario de mi módulo decide utilizar uno de los grandes módulos numéricos (como use bigint;), y luego usan inf o Math::BigInt->binf() para representar el infinito.

En algunos lugares parece funcionar bien, pero en otros, las comparaciones que deben ser ciertas o deben ser falsas terminan en el camino equivocado, lo que lleva a errores difíciles de localizar.

Me gustaría apoyar las otras nociones de infinito con algo que funcionará con números de perl normales y números de precisión arbitrarios.

Pero también me preocupa el rendimiento, ya que algunas de mis comparaciones con el infinito ocurren en circuitos internos estrechos. Obviamente, inf de Math::BigInt va a ser más lento que 9**9**9 (debido a métodos de llamada atada o sobrecargada en cada acceso). ¿Alguien ha lidiado con este problema en el pasado? Si es así, ¿cuál fue su solución?

He pensado en el uso de mi propia constante para el infinito, algo que se define así:

use constant INF => if_any_bignum_modules_loaded() 
        ? Math::BigInt->binf 
        : 9**9**9; 

Y a continuación, añadir la salvedad de que mi módulo que cualquier módulo bignum deben cargarse en primer lugar. ¿Esto suena sensato? ¿Hay una implementación confiable de if_any_bignum... por ahí, o debería lanzar la mía?

+0

posible duplicado de [¿Cómo creo o pruebo para NaN o infinito en Perl?] (Http://stackoverflow.com/questions/1185822/how-do-i-create-or-test-for-nan- or-infinito-en-perl) – Ether

+1

@Ether => lea la pregunta antes de cerrar la votación, ninguna de las respuestas en esa pregunta cubre esta pregunta ... –

+0

bien, eso no estaba muy claro, ya que las preguntas son idénticas . – Ether

Respuesta

8

Math::BigInt proporciona un método is_inf. Puede detectar el infinito para los dos números regulares de Perl, incluido el inf incorporado de Perl, como el retorno por 9**9**9, así como cualquier tipo de instancia de Math::Big* o esas cosillas mágicas que obtienes cuando usas bigint. Cargando Math::BigInt viene con apenas ningún tipo de gastos en todo - nada comparable a usar bigint de todos modos - y es un módulo central desde el comienzo mismo de Perl 5.

use 5.010; 
use Math::BigInt; 

say Math::BigInt->is_inf(42); 
say Math::BigInt->is_inf(9**9**9); 
say Math::BigInt->is_inf(Math::BigInt->binf); 

__END__ 
0 
1 
1 

También puede ser que desee echar un vistazo a la aplicación de esa método si realmente desea evitar cargar Math::BigInt en absoluto. Es bastante fácil ingresar a otro código con solo pequeñas modificaciones, aunque realmente recomendaría simplemente usar la funcionalidad del módulo directamente.

+0

Esto definitivamente parece una buena solución para todas las pruebas de bucle no internas. Tendré que comparar para ver el impacto en el rendimiento de los bucles internos. –

+1

Si le resulta demasiado lento para lo que está haciendo y encuentra la manera de implementar la misma funcionalidad de una manera más rápida, me gustaría aplicar sus parches a Math :: BigInt y enviarlos a CPAN. – rafl

+1

Suena bien, veré lo que puedo hacer. Me imagino que cambiar todas las coincidencias de expresiones regulares en llamadas a 'index 'sería un comienzo. –

Cuestiones relacionadas