13

私のモジュールの 1 つで、無限の概念に対処する必要があります。今日まで、私は9**9**9正の無限大を使用してきましたが、これはうまく機能し、高速であり、perl の内部で無限大として使用されているようです。

ただし、私のモジュールのユーザーが大きな数のモジュール ( などuse bigint;)の 1 つを使用することを決定し、 inforを使用Math::BigInt->binf()して無限を表すと、事態は少し危険になります。

正常に動作しているように見える場所もありますが、他の場所では、真または偽であるはずの比較が間違った方向に進み、バグの追跡が困難になります。

通常の perl 数値と任意精度の数値の両方で機能する何かで、無限のさまざまな他の概念をサポートしたいと思います。

しかし、無限大との比較の一部がタイトな内部ループで発生するため、パフォーマンスについても懸念があります。inffromは明らかMath::BigIntに遅くなります9**9**9(各アクセスで結ばれたメソッドまたはオーバーロードされたメソッドを呼び出すため)。過去にこの問題に対処した人はいますか? もしそうなら、あなたの解決策は何でしたか?

私は、無限に独自の定数を使用することを考えました。次のように定義しました。

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

そして、bignum モジュールを最初にロードする必要があるという警告をモジュールに追加します。これは理にかなっていますか?そこに信頼できる実装がif_any_bignum...ありますか、それとも自分で展開する必要がありますか?

4

1 に答える 1

10

Math::BigIntis_infメソッドを提供します。infreturn by などの Perl の組み込みの を含む通常の Perl 数と、 を使用しているときに得9**9**9られるあらゆる種類のMath::Big*インスタンスまたは魔法のようなものの両方の無限大を検出できますbigint。ローディングMath::BigIntにはほとんどオーバーヘッドがありませbigintん - とにかく使用することに匹敵するものはありません - 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

ロードをまったく避けたい場合は、そのメソッドの実装を確認することもできますMath::BigInt。モジュールの機能を直接使用することを強くお勧めしますが、少し変更するだけで他のコードにインライン化するのは簡単です。

于 2010-10-04T16:26:07.550 に答える