今回はごく普通の四捨五入です。ただし、整数除算の商を四捨五入して整数にします。
四捨五入の求め方については、JIS Z 8401:2019の規則Bがそれに該当します。せっかくですので該当部分を引用してみます。
元ネタでは負の数は対象にしていませんでしたが、せっかく実装し直すのでこちらでは負の数も対象にしました。
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
template <typename T> T round_half_up(T dividend, T divisor) { // 符号付き整数は、いったん符合無しで計算してから符号をあわせる。 if (is_signed<T>::value) { typedef typename make_unsigned<T>::type U; U lhs = dividend; U rhs = divisor; if (dividend < 0) lhs = -lhs; if (divisor < 0) rhs = -rhs; T t = round_half_up(lhs, rhs); if ((dividend < 0) != (divisor < 0)) t = -t; return t; } return (dividend + divisor / 2) / divisor; } |
今回もC++98以降で使えるようにしました。C++11より前のバージョンではmake_signedメタ関数が使えませんので、TR1かBoost C++ Librariesを使うようにしてください。
ところで、C99で導入されたround関数は四捨五入を行うためのものです。C++11からはC++でも標準関数になりました。ただし、負の数の扱いがどうやらJIS Z 8401のそれとは異なるようです。どちらがいいかではなく、実際にどのように振る舞うのかは把握しておくべきですし、どのような振る舞いが必要なのかに応じて使用するかどうかを判断するとよいでしょう。