前回は商のみを求めましたが、今回は余りも求めることにします。
商と余りなので、標準ライブラリのdiv_t等の型を使いたいところですが、テンプレート化しにくいですし、符合無し整数型も扱えませんので、独自にクラステンプレートを定義することにしました。
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
template <typename T> struct xdiv_t { T quot; T rem; }; template<class T> xdiv_t<T> xceil(T dividend, T divisor) { assert(is_integral<T>::value); T lhs = dividend; T rhs = divisor; if (rhs < 0) { lhs = -lhs; rhs = -rhs; } xdiv_t<T> r; r.quot = (lhs + (rhs - 1)) / rhs; r.rem = dividend - r.quot * divisor; return r; } |
例によってC++98以降で使えるようにはしましたが、is_integralにはTR1かBoost C++ Librariesを使うようにしてください。C++11以降なら標準ライブラリだけでOKです。使っているのはassertの引数だけなのでNDEBUGマクロを定義すれば標準ライブラリの範囲で大丈夫でしょう。
境界値のチェックはやっていませんのでオーバーフローが起きると未定義の動作になりますが、とりあえずこれで動作します。
以前のWebサイトには定数式にするためのメタ関数も掲載していたのですが、C++14以降ならconstexprを付けるだけで済みます。C++11のconstexprは制限が多いのでもう一工夫必要になります(今回は掲載しません)。