【PHP8.x】ceil関数の使い方

ceil関数の使い方について、初心者にもわかりやすく解説します。

作成日: 更新日:

基本的な使い方

ceil関数は、引数として与えられた数値を切り上げる処理を実行する関数です。この関数は、指定された浮動小数点数を、その数値以上の最小の整数値に丸めるために使用されます。例えば、ceil(4.3)を実行すると5.0が返され、ceil(9.9)を実行すると10.0が返されます。数値がすでに整数である場合、ceil(5.0)のように引数に整数値を与えても、その整数値が浮動小数点数として5.0として返されます。また、負の数に対しても機能し、ceil(-4.3)を実行すると-4.0が返されます。これは、-4.3以上の最小の整数が-4であるためです。

この関数の戻り値は、結果が整数値であっても常にfloat型となります。これは、PHPの数学関連の関数がしばしば浮動小数点数を扱うために、一貫性のあるデータ型を返すよう設計されているためです。

ceil関数は、例えば商品の数量や個数を計算する際に、端数が出た場合に必ず次の整数に切り上げて必要な量を確保したい場合や、リソースの配分などで最低限必要な整数単位を算出する場合などに非常に役立ちます。引数として切り上げたい数値を一つだけ指定するシンプルな使い方で、正確な切り上げ処理を実現できます。

構文(syntax)

1<?php
2echo ceil(3.14);
3?>

引数(parameters)

float $num

  • float $num: 整数に切り上げたい数値

戻り値(return)

float

与えられた数値を切り上げた浮動小数点数を返します。

サンプルコード

PHP ceil 関数、浮動小数点数精度問題のデモ

1<?php
2
3/**
4 * PHPの ceil() 関数における浮動小数点数精度問題の可能性を示すサンプルコード。
5 *
6 * 浮動小数点数 (float) の計算では、ごくわずかな誤差が生じることがあります。
7 * この誤差が原因で、ceil() 関数の結果が、見た目の数値から期待される結果と異なる場合があります。
8 * これは ceil() 関数自体のバグではなく、浮動小数点数演算の特性に起因します。
9 *
10 * システムエンジニアを目指す初心者の方へ:
11 * 特に厳密な精度が求められる計算では、浮動小数点数の丸め誤差に注意し、
12 * 必要に応じてBCMathなどの任意精度演算ライブラリの使用を検討してください。
13 */
14function demonstrateCeilPrecisionIssue(): void
15{
16    echo "--- ceil() 関数の浮動小数点数精度問題のデモンストレーション ---\n\n";
17
18    // シミュレーション: 本来は 10.0 を期待していたが、
19    // 複雑な計算誤差などでわずかに 10.0 を超えた値になった状況を仮定します。
20    // PHP_FLOAT_EPSILON は、浮動小数点数の最小の差を表す定数です。
21    // この値を加算することで、意図的にわずかな誤差をシミュレートします。
22    $valueWithTinyPositiveError = 10.0 + (PHP_FLOAT_EPSILON * 2);
23
24    echo "入力値 (わずかに 10.0 を超える): " . sprintf("%.17f", $valueWithTinyPositiveError) . "\n";
25    echo "ceil() の適用結果: " . ceil($valueWithTinyPositiveError) . "\n";
26    echo "期待が 10.0 であった場合、この結果 (11.0) は「バグ」のように見える可能性があります。\n\n";
27
28    // 別のケース: 厳密に 10.0 であるべき値が、わずかに 10.0 を下回る場合
29    // ceil() は切り上げのため、このケースでは通常、期待通り 10.0 が返されます。
30    // (例: 9.999999999999999 が 10.0 になる)
31    $valueWithTinyNegativeError = 10.0 - (PHP_FLOAT_EPSILON / 2);
32    echo "入力値 (わずかに 10.0 を下回る): " . sprintf("%.17f", $valueWithTinyNegativeError) . "\n";
33    echo "ceil() の適用結果: " . ceil($valueWithTinyNegativeError) . "\n";
34    echo "この場合、ceil() は期待通り 10.0 を返します。\n\n";
35
36    echo "まとめ:\n";
37    echo "ceil() 関数自体は数学的な定義に従って正確に動作します。\n";
38    echo "しかし、浮動小数点数演算の性質上、入力値に発生するごくわずかな誤差によって\n";
39    echo "意図しない切り上げ結果となり、誤って「バグ」と認識されることがあります。\n";
40}
41
42// 関数を実行
43demonstrateCeilPrecisionIssue();

PHPのceil()関数は、引数として与えられた浮動小数点数$numを、自身より大きいか等しい最も近い整数に切り上げる関数です。引数$numには浮動小数点数を指定し、戻り値は切り上げられた整数値が浮動小数点数型で返されます。

このサンプルコードは、ceil()関数が浮動小数点数演算の特性により、予期せぬ結果を返す可能性を示しています。具体的には、浮動小数点数の計算ではごくわずかな誤差が生じることがあり、例えば厳密には10.0と期待される値が、実際には10.0000000000000001のようにわずかに10.0を超えた値になることがあります。このような場合、ceil()関数はそのわずかな誤差によって、期待される10.0ではなく11.0を返します。これはceil()関数自体のバグではなく、浮動小数点数演算の精度限界に起因するものです。サンプルコードでは、PHP_FLOAT_EPSILONを用いて、意図的にわずかな誤差をシミュレートしています。

システム開発において厳密な精度が求められる計算を行う際は、このような浮動小数点数の丸め誤差に十分注意が必要です。必要に応じて、BCMathのような任意精度演算ライブラリの使用を検討することで、より正確な計算結果を得ることができます。

PHPのceil関数は数学的な切り上げを正確に行いますが、浮動小数点数(float)の計算にはごくわずかな誤差が生じることがあります。この誤差により、本来10.0になるべき数値がわずかに10.0を超えると、ceilは11.0を返す可能性があります。これはceil関数自体のバグではなく、浮動小数点数演算の避けられない特性です。厳密な精度が求められる計算では、この丸め誤差に特に注意し、必要に応じてBCMathなどの任意精度演算ライブラリの利用をご検討ください。

PHPで指定桁数で数値を切り上げる

1<?php
2
3/**
4 * 指定された小数点以下の桁数で数値を切り上げます。
5 *
6 * PHPの標準的な`ceil()`関数は、常に数値を最も近い整数に切り上げます。
7 * 特定の小数点以下の桁数で切り上げたい場合は、
8 * 数値を一時的に指定桁数分だけ乗算して小数点位置を右に「シフト」し、
9 * `ceil()`を適用して整数に切り上げ、
10 * その後、同じ桁数分だけ除算して小数点位置を左に「シフトバック」する必要があります。
11 *
12 * @param float $number 切り上げたい数値。
13 * @param int $decimalPlaces 切り上げたい小数点以下の桁数。デフォルトは2です。
14 * @return float 指定された小数点以下の桁数で切り上げられた数値。
15 */
16function ceilToDecimalPlaces(float $number, int $decimalPlaces = 2): float
17{
18    // 小数点以下の桁数に応じた乗数(例: 2桁なら 10^2 = 100)を計算します。
19    $factor = 10 ** $decimalPlaces;
20
21    // 数値を乗算して小数点位置を右にシフトし、`ceil()`で整数に切り上げ、
22    // その後除算して小数点位置を左にシフトバックします。
23    return ceil($number * $factor) / $factor;
24}
25
26// 例: 123.456 を小数点以下2桁で切り上げる
27$originalNumber = 123.456;
28$roundedNumber = ceilToDecimalPlaces($originalNumber, 2);
29
30echo "元の数値: " . $originalNumber . PHP_EOL;
31echo "小数点以下2桁で切り上げた数値: " . $roundedNumber . PHP_EOL; // 出力: 123.46
32
33// 別の例: 小数点以下3桁で切り上げる
34$anotherNumber = 50.12345;
35$roundedToThreeDecimals = ceilToDecimalPlaces($anotherNumber, 3);
36
37echo "元の数値: " . $anotherNumber . PHP_EOL;
38echo "小数点以下3桁で切り上げた数値: " . $roundedToThreeDecimals . PHP_EOL; // 出力: 50.124
39
40// 負の数の場合も同様に機能します (ceilは正の無限大方向への切り上げです)
41$negativeNumber = -10.9876;
42$roundedNegativeNumber = ceilToDecimalPlaces($negativeNumber, 2);
43
44echo "元の負の数値: " . $negativeNumber . PHP_EOL;
45echo "小数点以下2桁で切り上げた負の数値: " . $roundedNegativeNumber . PHP_EOL; // 出力: -10.98
46

PHP 8のceil関数は、指定された数値を常に「より大きな整数」に切り上げる機能を持っています。例えば、123.45であれば124に、-10.98であれば-10に切り上げます。しかし、この関数は特定の小数点以下の桁数で数値を切り上げるようには設計されておらず、常に整数に切り上げます。

提供されたサンプルコードは、このceil関数を応用して「指定された小数点以下の桁数で数値を切り上げる」ためのカスタム関数ceilToDecimalPlacesを提供しています。この関数は、引数として切り上げたい$number(数値)と、切り上げたい$decimalPlaces(小数点以下の桁数、デフォルトは2)を受け取ります。

内部的な仕組みとしては、まず指定された桁数に応じて数値を一時的に10の累乗で乗算し、小数点位置を右にずらします。これにより、指定桁数までが整数の部分となるようにします。その状態でPHP標準のceil関数を適用して整数に切り上げ、最後に再び同じ乗数で除算して小数点位置を元の場所に戻します。これにより、指定された桁数で正確に切り上げられた数値が戻り値として得られます。

例えば、123.456を小数点以下2桁で切り上げる場合、ceilToDecimalPlaces(123.456, 2)と呼び出すと、最終的に123.46が出力されます。また、50.12345を3桁で切り上げると50.124となります。負の数に対しても同様に機能し、-10.9876を2桁で切り上げると-10.98となります。この関数を使うことで、より柔軟な数値の切り上げ処理が可能になります。

PHPの標準関数ceil()は、与えられた数値を常に「最も近い、その数値以上の整数」に切り上げます。小数点以下の特定の桁数で切り上げたい場合は、サンプルコードのように数値を一時的に10の累乗で乗算・除算して小数点位置を調整する工夫が必要です。

浮動小数点数(float型)の計算では、ごく稀に内部的な精度誤差が生じることがあります。このため、特に金銭計算など厳密な正確性が求められる場面では、この方法だけでなく、int型への変換や、より高精度な計算が可能なbcmath拡張機能の利用も検討してください。

また、ceil()は負の数に対しても「正の無限大方向への切り上げ」を行うため、例えば-10.9876を小数点以下2桁で切り上げると-10.98になります。この特性を理解して利用することが重要です。このカスタム関数は、ceil()の基本的な挙動を理解し、その応用例として活用できます。

関連コンテンツ