PHPでは、パック関数は非常に実用的なツールであり、指定された形式のバイナリ文字列にデータをパッケージ化するために使用され、ネットワーク伝送、ファイルストレージ、その他のシナリオでよく使用されます。特に、フローティングポイント番号に関しては、 Packは「F」と「D」の2つの形式コードを提供します。これは似ていますが、実際には本質的な違いがあります。今日は、2つとフローティングポイント精度トラップの違いを調査します。
パック関数の基本的な使用法は次のとおりです。
pack(string $format, mixed ...$values): string
フォーマット文字列に基づいて、後続のパラメーターをバイナリデータに変換します。
その中で、一般的な浮動小数点形式コードは次のとおりです。
「F」 :シングルエシジョンフローティングポイント番号(フロート、4バイト)
「D」 :ダブル精度の浮動小数点番号(ダブル、8バイト)
「F」は、 4バイトのシングルエシジョンフローティングポイント番号、つまりフロートタイプに対応し、IEEE 754標準の32ビットフローティングポイント番号形式に従います。
「D」は、 8バイトの二重精度フローティングポイント数、つまりダブルタイプに対応し、IEEE 754標準の64ビットフローティングポイント形式に従います。
これは、 「d」は、範囲が大きく、精度が高いフローティングポイント数を表すことができるのに対し、 「F」は保管スペースでは小さく、精度は限られていることを意味します。
単一精度の浮動小数点数( "f" )は、約7桁の精度を持っています。
二重精度の浮動小数点数( "d" )は、約15〜16桁の精度があります。
非常に正確なフローティングポイントデータが必要な場合は、 「D」を使用することをお勧めします。
パックのフローティングポイント番号形式は、マシンエンディアンネス(大規模)の順序の影響を受けます。システムは通常、小エンディアン性を使用しますが、プラットフォーム間で送信するときは特別な注意を払う必要があります。
<?php
$value = 0.1 + 0.2;
$packed_f = pack("f", $value);
$packed_d = pack("d", $value);
echo "元の値:$value\n";
echo "単一の精密パッケージ後の16進数:".bin2hex($packed_f)."\n";
echo "二重精度包装後の16進数:".bin2hex($packed_d)."\n";
出力例:
元の値:0.3
単一の精密パッケージ後の16進数:9a99993e
二重精度包装後の16進数:9a9999999999b93f
入力は0.3ですが、単一の精度と二重精度のバイナリ表現が異なることがわかります。これは、浮動小数点数自体が特定の小数を完全に表すことができず、単一の精度の誤差がさらに大きいためです。
高精度のフローティングポイント番号を保存または転送する必要がある場合、 「D」が推奨されます。
スペースと精度の要件が高くない場合は、 「F」を使用します。
ネットワークプロトコルまたはファイル形式を扱う場合、誤解を避けるためにプロトコルで必要なフローティングポイント形式を明確にします。
クロスプラットフォームアプリケーションの場合、Endiannessの問題を考慮することをお勧めします。パックと開梱を使用する場合、エンディアンネスを統合する必要があります。
PHP公式マニュアルのパッケージ関数説明アドレス: