PHP開発では、 CEIL()関数はしばしば切り上げるために使用されますが、その結果は予想される整数ではなく、しばしば混乱していることがわかります。実際、この状況の基本的な理由は、浮動小数点数の表現と操作エラーです。この記事では、この問題の原因を詳細に分析し、効果的なソリューションを提供します。
CEIL()関数の関数は、数値を上方に回り、その数以上を最小の整数を返すことです。例えば:
<?php
echo ceil(3.2); // 出力 4
echo ceil(7.0); // 出力 7
?>
通常の状況では、この機能は単純で直感的です。
場合によっては、 ceil()関数は次のような異常な結果をもたらします。
<?php
$num = 1.9999999999999998;
echo ceil($num); // 结果出力 2,期待に応えます
$num = 1.9999999999999996;
echo ceil($num); // 结果出力 1,思いがけず
?>
なぜ後者は2の代わりに1の結果を持っているのですか?これは、実際には、浮動小数点数の精度制限が原因です。
PHPのフローティングポイントは、IEEE 754標準に基づく二重精度の浮動小数点数です。この表現には固有の精度の制限があり、いくつかの小数を正確に表現できません。例えば:
<?php
var_dump(0.1 + 0.2);
// 出力 float(0.30000000000000004)
?>
これらの小さなエラーは、数学操作を実行するときに蓄積され、 ceil()で処理される数値が実際には予想よりもわずかに小さく、またはわずかに大きくなります。
次の例を考えてみましょう。
<?php
$num = 2.0000000000000004;
echo ceil($num); // 出力 3
$num2 = 1.9999999999999996;
echo ceil($num2); // 出力 2,しかし、実際の希望はです 2
?>
num2は2未満に見えますが、浮動小数点精度のために数値がわずかに2未満として保存され、 Ceil()は1ではなく最大2になります。
このタイプのエラーは、財務計算、測定変換の単位、およびその他のシナリオに深刻な問題につながる可能性があります。
最初にラウンド()関数を使用して小数点以下の場所の数を制限し、次にceil()を使用して処理できます。
<?php
$num = 1.9999999999999996;
$num = round($num, 8); // 予約する8位小数
echo ceil($num); // 结果出力 2,期待に応えます
?>
この方法は、フローティングポイントエラーの影響を効果的に削減します。
精度要件が非常に高い場合は、PHPのBCMATH関数を使用できます。
<?php
$num = "1.9999999999999996";
$result = bcadd($num, '0', 0); // 予約する0位小数,これは、下向きに丸くなることに相当します
if (bccomp($num, $result, 10) > 0) {
$result = bcadd($result, '1', 0);
}
echo $result; // 出力 2
?>
BCMATHは文字列を使用して数字を表し、浮動ポイントエラーを回避します。
数値範囲が許可されている場合、最初に数値を拡大できます。
<?php
$num = 1.9999999999999996;
$scale = 8;
$num_scaled = (int)($num * pow(10, $scale));
$num_ceil = ceil($num_scaled / pow(10, $scale));
echo $num_ceil; // 出力 2
?>
この方法は、浮動小数点精度エラーの問題を軽減することもできます。
PHPの浮動小数点数には、基礎となるバイナリ表現のために精度エラーがあります。
CEIL()関数自体はエラーを発生させませんが、エラーにより入力パラメーターが予期せぬ原因になり、結果が逸脱します。
問題を効果的に回避するために、Round() 、BCMath拡張機能、またはズームインテクニックを使用します。
浮動小数点数の性質を理解し、適切な対策を講じることによってのみ、PHPプロジェクトで正確で信頼できる役割を果たすことができます。