最新リリース: 1.0.0 ベータ版
オーバーフロー時にラップアラウンドする整数の算術演算用の PHP 5.3 以降のライブラリ。
注意
このライブラリは、整数に対して算術演算を適切に実行する方法として使用することを目的としていないため、ネイティブ算術演算子やそのような目的で設計された他のライブラリの代わりに使用しないでください。
大きな正の整数を大きな負の整数にオーバーフローする他の言語とは異なり、PHP は実際に整数を浮動小数点数にオーバーフローします。ほとんどの場合、算術オーバーフローは特別な処理が必要な異常な状況として扱う必要があります。ただし、TCP シーケンス番号やハッシュ計算などの特定のアルゴリズムなど、このようなラップアラウンド動作が実際に役立つ場合もあります。このユーティリティ クラスは、その動作に従って動作する基本的な算術関数を提供します。
これを説明するために、次の例を考えてみましょう。
// Output on 64-bit system: float(9.2233720368548E+18)
var_dump ( PHP_MAX_INT + 1 );
// Output on 64-bit system: int(-9223372036854775808)
var_dump (IntMath:: add ( PHP_MAX_INT , 1 ));
前に示したように、ネイティブ算術演算子を使用してサポートされている最大の整数に 1 を加算すると、浮動小数点数が生成されます。対照的に、IntMath::add() を使用するとオーバーフローが発生し、このビルドの PHP でサポートされている最小の整数になります。
API はソース コードに詳しく文書化されています。さらに、ブラウザでより便利に閲覧できる HTML バージョンも用意されています。
Composer を使用してパッケージをインストールします。
$ composer require phpcommon/intmath
現時点では、基本的な四則演算 (加算、減算、乗算、除算) と否定のみがサポートされています。
整数値の場合、否定はゼロからの減算と同じです。 PHP では整数に 2 の補数表現が使用され、2 の補数値の範囲は対称ではないため、最大の負の整数を否定すると、同じ最大の負の数になります。オーバーフローが発生したにもかかわらず、例外はスローされません。
すべての整数値$a
について、 -$a
(~$a) + 1
と等しくなります。
API の使用例:
// Outputs int(-100)
var_dump (IntMath:: negate ( 100 ));
2 つの整数を加算した結果は、十分に広い 2 の補数形式で表される真の数学的結果の下位ビットです。オーバーフローが発生した場合、結果の符号は 2 つの値の数学的合計の符号と同じではない可能性があります。この場合、オーバーフローにもかかわらず、例外はスローされません。
API の使用例:
// Outputs int(300)
var_dump (IntMath:: add ( 100 , 200 ));
正の数を減算すると、同じ大きさの負の数を加算した場合と同じ結果が得られます。さらに、ゼロからの減算は否定と同じです。結果は、十分に広い 2 の補数形式で表現された真の数学的結果の下位ビットです。オーバーフローが発生した場合、結果の符号は 2 つの値の数学的差の符号と同じではない可能性があります。この場合、オーバーフローにもかかわらず、例外はスローされません。
API の使用例:
// Outputs int(90)
IntMath:: subtract ( 100 , 10 );
2 つの整数を乗算した結果は、十分に広い 2 の補数形式で表される真の数学的結果の下位ビットです。オーバーフローが発生した場合、結果の符号は 2 つの値の数学的積の符号と同じではない可能性があります。この場合、オーバーフローにもかかわらず、例外はスローされません。
API の使用例:
// Outputs int(200)
IntMath:: multiply ( 100 , 2 );
除算では、結果がゼロに向かって丸められます。したがって、結果の絶対値は、2 つのオペランドの商の絶対値以下の可能な最大の整数になります。 2 つのオペランドの符号が同じ場合、結果は 0 または正となり、2 つのオペランドの符号が反対の場合、結果は 0 または負になります。
このルールを満たさない特殊なケースが 1 つあります。被除数がその型で可能な最大の大きさの負の整数で、除数が-1
の場合、整数オーバーフローが発生し、結果は被除数と等しくなります。この場合、オーバーフローにもかかわらず、例外はスローされません。一方、整数除算の除数の値が0
の場合は、 DivisionByZeroException
がスローされます。
API の使用例:
// Outputs int(50)
IntMath:: divide ( 100 , 2 );
最近の変更点の詳細については、CHANGELOG を参照してください。
$ composer test
詳細については、テスト ドキュメントを参照してください。
パッケージへの貢献はいつでも大歓迎です!
詳細については、「貢献と実施」を参照してください。
セキュリティ関連の問題を発見した場合は、問題トラッカーを使用する代わりに、[email protected] に電子メールを送信してください。
このパッケージのすべての内容は、MIT ライセンスに基づいてライセンスされています。