2010-10-04 7 views
13

In einem meiner Module muss ich mich mit dem Konzept der Unendlichkeit beschäftigen. Bis jetzt habe ich 9**9**9 als positive Unendlichkeit verwendet, und das scheint gut zu funktionieren, ist schnell und scheint das zu sein, was Perls Inneres als Unendlichkeit benutzt.Wie kann man in einem Perl-Modul am besten auf Unendlichkeit prüfen?

Allerdings wird es etwas heikel, wenn ein Benutzer von meinem Modul eine der großen Anzahl Module zu verwenden, entscheidet (wie use bigint;), und sie verwenden, dann inf oder Math::BigInt->binf() Unendlichkeit darzustellen.

An einigen Stellen scheint es gut zu funktionieren, aber in anderen, führen Vergleiche, die wahr sein sollten oder falsch sein sollten, auf den falschen Weg, was dazu führte, dass Bugs schwer zu finden waren.

Ich möchte die verschiedenen anderen Begriffe der Unendlichkeit mit etwas unterstützen, das sowohl mit normalen Perl-Zahlen als auch mit beliebigen Präzisionszahlen funktionieren wird.

Aber ich habe auch Bedenken hinsichtlich der Leistung, da einige meiner Vergleiche mit Unendlichkeit in engen inneren Schleifen auftreten. Offensichtlich inf von Math::BigInt wird langsamer sein als 9**9**9 (wegen entweder Aufruf gebunden oder überladen Methoden bei jedem Zugriff). Hat sich jemand in der Vergangenheit mit diesem Problem beschäftigt? Wenn ja, was war Ihre Lösung?

Ich habe darüber nachgedacht, meine eigene Konstante verwendet für die Unendlichkeit, definiert etwas wie folgt aus:

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

Und dann das Vorbehalt zu meinem Modul, das alle bignum Module zuerst geladen werden soll. Klingt das sinnvoll? Gibt es eine zuverlässige Implementierung von if_any_bignum... da draußen, oder sollte ich meine eigene rollen?

+0

mögliche Duplikate von [Wie erstelle oder teste ich NaN oder Unendlich in Perl?] (Http://stackoverflow.com/questions/1185822/how-do-i-create-o-test-for-nan- oder-infinity-in-perl) – Ether

+1

@Ether => Bitte lesen Sie die Frage vor der Abstimmung zu schließen, keine der Antworten in dieser Frage diese Frage abdecken ... –

+0

ok, das war nicht sehr klar, da die Fragen identisch sind . – Ether

Antwort

8

Math::BigInt bietet eine is_inf Methode. Es kann Unendlichkeit für beide regulären Perl-Nummern, einschließlich Perls eingebauter inf, wie die Rückgabe von 9**9**9, sowie jede Art von Math::Big* Instanz oder die magischen Dinge, die Sie erhalten, wenn Sie bigint verwenden, erkennen. Loading Math::BigInt kommt fast ohne Aufwand überhaupt - keine vergleichbaren bigint ohnehin mit - und ist ein Kernmodul der ersten Stunde von 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 

Sie könnten auch einen Blick auf die Umsetzung der, dass zu wollen Methode, wenn Sie wirklich vermeiden wollten, Math::BigInt zu laden. Es ist einfach genug, anderen Code mit nur leichten Modifikationen zu integrieren, obwohl ich wirklich nur die Funktionalität direkt aus dem Modul empfehlen würde.

+0

Dies scheint definitiv eine gute Catch-All-Lösung für alle nicht-inneren Loop-Tests. Ich muss einen Benchmark erstellen, um die Auswirkungen auf die inneren Schleifen zu sehen. –

+1

Wenn Sie feststellen, dass es für alles, was Sie tun, zu langsam ist, und eine Möglichkeit finden, die gleiche Funktionalität schneller zu implementieren, würde ich mich sehr freuen, Ihre Patches auf Math :: BigInt anzuwenden und an CPAN zu senden. – rafl

+1

Klingt gut, ich werde sehen, was ich tun kann. Ich würde mir vorstellen, alle Regex-Übereinstimmungen in Aufrufe von 'index' zu ändern, wäre ein Anfang. –