プログラムの中で計算をするときに、絶対値を取得したい時はありませんか? absという関数を使うと解決できます。
今回はabs関数について、解説します。
ぜひ参考にしてみてください。
目次
absの使い方を理解する
absという関数は、一言で言うと「絶対値を取得する」関数です。
https://www.php.net/manual/ja/function.abs.php
number
の絶対値を返します。
absという関数の名前は「absolute value(絶対値)」に由来しているということも一緒に覚えておくと、プログラムを書くときに思い出しやすいですね。
コードとして理解する
absをプログラムの中で使うときに注意しておかないといけないのは、引数として渡す値の型です。
abs関数は仕様として、int型を渡せばint型を返し、float型を渡すとfloat型を返すようになっています。
では、実際にコードでabsの仕様を確認していきます。例えば、absに「-15」という整数型の値を渡してみます。
1 |
echo abs(-15) |
これを実行すると、結果は「15」と表示されます。では、次にfloat型の値を渡すとどうなるでしょうか。
例えば、absに「-4.6」というfloat型の値を渡してみます。
1 |
echo abs(-4.6) |
これを実行すると、結果は「4.6」となります。では次に、実験として仕様にはない文字列を渡すとどうなるのでしょうか。
例えば、absに「hoge」という文字列を渡して、実行してみます。
1 |
echo abs(“hoge”) |
すると、以下のようなエラーが表示されてしまいました。
1 |
Warning: Use of undefined constant “hoge” - assumed '“hoge”' (this will throw an Error in a future version of PHP) |
リファレンスにもあるように、仕様にないのでPHPのプログラムとしてうまく動作しないようになっています。
では、ここまでのまとめです。
・int型の値をabsに渡すとint型の値が返ってくる
・float型の値をabsに渡すとfloat型の値が返ってくる
・文字列を渡すと、エラーとなり実行することができない
absという関数の使い方、仕様を確認しました。
では、次に実際にどんな時にabsは使うのか、その活用シーンをプログラムも併せて解説していきます。
金額の差分を計算するときに使う
absの活用シーンの一例として、金額の差分の計算があります。
単に金額の差分を考えるとプラス/マイナスの符号は必要ありません。
そして、差分を考えるためだけに金額を「(大きい値) – (小さい値)」となるような処理を書くのは面倒です。
こういうときには、absを利用して以下のようにプログラムを書けばOKです。
1 2 3 4 |
$price_a = 1000; $price_b = 2000; echo abs($price_a - $price_b); |
出力結果は以下のようになります。
1 |
1000 |
時間を計測するときに使う
absは時間を計測するときに便利です。例えば、次のようなプログラムを考えてみます。
1 2 3 4 5 6 7 8 |
$time_a = "05:00"; $time_b = "15:00"; $diff = $time_b - $time_a; echo date("H:i\n", $diff); $diff = $time_a - $time_b; echo date("H:i\n", $diff); |
このプログラムの仕様を簡単にまとめると、
・$time_b – $time_aの差分を計算する
・$time_a – $time_bの差分を計算する
・それらの差分をdateという関数で「(時):(分)」の形式として出力する
です。想定している出力としては、どちらも「9:00」が表示されることです。
しかし、このプログラムを実行してみると、こんな結果になります。
1 2 |
09:00 08:59 |
このように想定とは違う結果が出力されてしまいます。
このような結果になってしまう原因は、時間の差を計算の順序にあります。
想定する動作にするためには「(大きい値) – (小さい値)」で差分を計算しなければなりません。
ここでabsの登場です。
以下のようにabsを利用して時間の差分を計算するように修正します。
1 2 3 4 5 6 7 8 |
$time_a = "05:00"; $time_b = "15:00"; $diff = abs($time_b - $time_a); echo date("H:i\n", $diff); $diff = abs($time_a - $time_b); echo date("H:i\n", $diff); |
これで実行してみると、このようになります。
1 2 |
09:00 09:00 |
これで想定どおりの動作になりました。
このように時間に関連するようなプログラムを書くときには、absを利用するとうまく解決できます。
ここまで、金額の差分を計算する場合と時間の差分を計算する場合を紹介しました。
他にも以下のような場合が当てはまるときはabsを利用することを考えてみてください。
・「(大きい値) – (小さい値)」 が必要ない
・プラス/マイナスの符号が必要ない
・時間の差分を計算する
実際のコードではここで使われている
absという関数は、実際のフレームワークでも利用されています。
今回は実際にWEBアプリ開発で利用されているCakePHPとCodeIgniterのコードを例として紹介します。
CodeIgniter
CodeIngniterというフレームワークでは、CI_Emailというクラスで実際に利用されています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
/** * Set RFC 822 Date * * @return string */ protected function _set_date() { $timezone = date('Z'); $operator = ($timezone[0] === '-') ? '-' : '+'; $timezone = abs($timezone); $timezone = floor($timezone/3600) * 100 + ($timezone % 3600) / 60; return sprintf('%s %s%04d', date('D, j M Y H:i:s'), $operator, $timezone); } |
_set_dateという関数は、メールの送受信として日付をセットするCodeIgniterで使える関数です。
これは「 」の項でまとめている、「時間の差分を計算する」場合にあてはまりますね。
CakePHP
Cake PHPというフレームワークのNumberクラスのcurrencyという関数の中で利用されています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
public static function currency($value, ?string $currency = null, array $options = []): string { $value = (float)$value; $currency = $currency ?: static::getDefaultCurrency(); if (isset($options['zero']) && !$value) { return $options['zero']; } $formatter = static::formatter(['type' => static::getDefaultCurrencyFormat()] + $options); $abs = abs($value); if (!empty($options['fractionSymbol']) && $abs > 0 && $abs < 1) { $value *= 100; $pos = $options['fractionPosition'] ?? 'after'; return static::format($value, ['precision' => 0, $pos => $options['fractionSymbol']]); } $before = $options['before'] ?? ''; $after = $options['after'] ?? ''; $value = $formatter->formatCurrency($value, $currency); return $before . $value . $after; } |
currencyは「通貨」という意味なので、通貨の計算に関する処理を行っている関数になります。
まとめ
いかがでしたか? 今回はabsで絶対値を取得する方法を紹介しました。
絶対値の計算したい場面というのは、意外と多いです。
ぜひ参考にしてみてください。