PHPでは、 bindec()は、バイナリ文字列を小数点に変換するための非常に実用的な機能です。その基本的な使用法は非常に簡単です:
echo bindec('1010'); // 出力 10
しかし、着信バイナリ文字列が長すぎてPHPでサポートされている整数範囲を超えるとどうなりますか?これは、特に多数を扱う場合、または高精度計算を必要とする場合に、調査する価値のある質問です。
まず、PHPの整数( INT )の範囲が基礎となるプラットフォームによって制限されていることを理解する必要があります。ほとんどの64ビットシステムでは、 PHP_INT_MAXは922337203685475807であり、32ビットシステムの場合、 2147483647しかありません。
渡されるバイナリ文字列で表される値がこの範囲を超えると、 bindec()は戻り値をフロートタイプに自動的に変換します。この動作は、PHPのタイプ変換メカニズムの一部であり、精度の損失をもたらす可能性があります。
例を見てみましょう:
$binary = '11111111111111111111111111111111111111111111111111111111111111111';
$result = bindec($binary);
var_dump($result);
このバイナリ文字列の長さは65ビットで、64ビット整数の最大値よりもはるかに大きいです。操作の結果は次のとおりです。
float(1.84467440737096E+19)
ご覧のとおり、返品値は浮動小数点数であり、科学的表記で表現されています。これも意味します:
精度は精度ではなくなる場合があります。
この結果をさらに数学的な計算に使用すると、予測不可能なエラーが導入される場合があります。
整数範囲を正確に超えるバイナリ番号を処理する必要がある場合は、PHPのBCMATHまたはGMP拡張を使用することを検討してください。
BCMATHの使用:
$binary = '10101010101010101010101010101010101010101010101010101010101010101';
$decimal = '0';
$length = strlen($binary);
for ($i = 0; $i < $length; $i++) {
$bit = $binary[$i];
$power = bcpow('2', $length - $i - 1);
if ($bit === '1') {
$decimal = bcadd($decimal, $power);
}
}
echo $decimal; // 出力精确的十进制值
GMPの使用:
$binary = '10101010101010101010101010101010101010101010101010101010101010101';
$gmp = gmp_init($binary, 2);
echo gmp_strval($gmp); // 精确出力
BCMATHは、より良い互換性を備えた純粋なPHP実装です。 GMPライブラリのパフォーマンスは強力ですが、サーバーサポートが必要です。
IPアドレスの処理、ビット許可管理、暗号化アルゴリズムなどの一部のデータ処理シナリオでは、大規模なバイナリデータの処理は一般的なタスクです。 bindec()を直接使用する場合、次のとおりです。
bindec('1001011100101101001010010010101010010101010101010101010101010101');
また、ユーザー許可マスクとして使用しようとすると、その後の判断で正確さが失われ、セキュリティリスクが発生する可能性があります。数値の精度を確保するために、BCMATHまたはGMPを優先する必要があります。
Bindec()は、小型および中程度のバイナリ文字列を処理する場合に効率的で便利ですが、入力データがPHP整数の範囲外にある場合、その動作は自動的に変動点タイプに戻り、精度の問題を引き起こす可能性があります。開発者は、高ビットのバイナリ番号を扱う際に特に注意する必要があり、データの正確性を確保するために必要に応じて高精度の数学ライブラリを使用する必要があります。