LoginSignup
0
1

More than 3 years have passed since last update.

BC Math用ceil・floor関数

Posted at

概要

BC Mathを用いて計算をする過程で少し特殊なceil・floor関数が必要になったので,このコードを参考に作成しました.

実装

function bcceil($number, $scale = null)
{
    if (strpos($number, '.') !== false) {
        [$integer, $decimal] = explode('.', $number);

        if (isset($scale)) $decimal = substr($decimal, 0, $scale);
        $decimal = str_replace('0', '', $decimal);

        if ($decimal === '' || $integer[0] == '-') return $integer;
        return bcadd($integer, 1, 0);
    }
    return $number;
}

function bcfloor($number, $scale = null)
{
    if (strpos($number, '.') !== false) {
        [$integer, $decimal] = explode('.', $number);

        if (isset($scale)) $decimal = substr($decimal, 0, $scale);
        $decimal = str_replace('0', '', $decimal);

        if ($decimal === '' || $integer[0] != '-') return $integer;
        return bcsub($integer, 1, 0);
    }
    return $number;
}

元のコードとの違い

小数点以下の桁数を指定しての切り上げ・切り捨てができるようになっています.具体的には1.0010という数に対して$scaleを変化させると

切り上げ後
bcceil('1.0010', 0) '1'
bcceil('1.0010', 1) '1'
bcceil('1.0010', 2) '1'
bcceil('1.0010', 3) '2'
bcceil('1.0010', 4) '2'

このように動作します.これで含めたくない桁を除いて切り上げ・切り捨てができるようになりました(floorの方はあまり意味がない気もしますが).

また,元のコードではbcceilbcfloorの実装にbcroundが必要になっているのに対し,こちらのコードではそれぞれが単体で動くようになっています.

解説

bcceilについて解説します.まず,

[$integer, $decimal] = explode('.', $number);

とすることで,整数部と小数部に分割することができます(このような書き方は関数の返り値を受け取る際などに便利です).次に桁数$scaleの指定がある場合は,

$decimal = substr($decimal, 0, $scale);

この部分で指定桁数まで切り出されます.その後,

$decimal = str_replace('0', '', $decimal);

0がすべて消去されます.したがって小数部がすべて0の場合に限り,$decimalは空文字となります.最後に

if ($decimal === '' || $integer[0] == '-') return $integer;
return bcadd($integer, 1, 0);

この部分で切り上げるかどうかの判定を行うのですが,前述の通り$decimalが空文字の場合は小数部がすべて0であるので切り上げなし.小数部が残っている場合でも,負数の場合はプラス方向への切り上げになるので切り上げなし.正数の場合は切り上げが発生する,ということになります.

注意点

これらの関数の返り値をint型にキャストするとオーバーフローが起こる可能性があるので注意が必要です.組み込み関数のfloorceilでも同様の理由から,返り値がfloat型になっています.

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1