0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

プログラミングテクニック 徐算した数値の切り上げ

Last updated at Posted at 2023-09-25

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; 
}
0
2
6

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
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?