AtCorderで使うテクニックを備忘録として書き残しておく。
いきなり一般化するのは難しいので
まずは前提として1、2を考える。
1.登場する値は正の値とする。(負の場合では成立しない)
2.n+aの桁溢れが発生しない程度の数値の大きさ
通常の演算では数字は切り捨てとなる。つまり大学受験で時々登場するガウス記号が演算結果に適応されている。
切り捨ての場合
int main()
{
int n = 5;
int a = 2;
// 結果を出力(2を出力)
std::cout << n / a << std::endl;
}
切り上げ時には下記の通り n/aを(n+a-1)/aに書き換える。
n/a+1にした場合はn/aがちょうど割り切れる場合でも加算されてしまうため、全ての正の実数で条件を満たせない。
切り上げの場合 その1
int main()
{
int n = 5;
int a = 2;
// 結果を出力(3を出力)
std::cout << (n+a-1) / a << std::endl;
}
前提2の桁溢れを防ぐためには以下の方法で回避できる。
割り切れる場合以外は1加算すれば良いので、判定文を利用する。
切り上げの場合 その2
int main()
{
int n = 5;
int a = 2;
// 結果を出力(3を出力)
std::cout << n/a + (n%a != 0) << std::endl;
}
さらに前提1で対象外としていた負の値も考慮する。
負の場合で余計な処理を加えなければ良いので,排他的論理和を含んだ判定分 (n^a) >= 0 を利用する。
切り上げの場合 その3
int main()
{
int n = 5;
int a = -2;
// 結果を出力(-2を出力)
// -2 + 0 * 1
std::cout << n/a + ((n^a) >= 0) * (n%a != 0) << std::endl;
}