LoginSignup
2
0

More than 5 years have passed since last update.

[小ネタ]最近のコンピュータではINT32_MAX回のループでも意外と回ると気づいた話

Last updated at Posted at 2017-07-30

32ビット整数の最大値って、とてつもなく大きい印象があったのですが。
そして、そんなすごい回数のループなんて、全然終わらない、という印象があったのですが。

家にある、数年前のCore i5のパソコンで、なんとなくやってみました。
最適化などのオプションは何もつけてません。

#include <stdio.h>
int main() {
    int i;
    long long s = 0;
    for(i=0;i<0x7FFFFFFF;i++) s += i;
    printf("%lld\n", s);
}
$ time ./a.out 
2305843005992468481

real    0m5.063s
user    0m5.062s
sys     0m0.000s

もちろん、ループの中が重くなれば、どうなるかは想像に難くないですが。
例えば、以下のように、少し重くするだけで、

#include <stdio.h>
int main() {
    int i;
    long long s = 0;
    for(i=0;i<0x7FFFFFFF;i++) if(i%2) s /= i;
    printf("%lld\n", s);
}
$ time ./a.out 
0

real    0m14.842s
user    0m14.780s
sys     0m0.007s

と、時間も増えてしまいました。

さて。0〜INT32_MAX-1の間で、平方根が整数になるものを力技で求めてみましょう。
(普通は、こんな効率悪い計算せずに、整数を2乗することで求めるかと思いますが)

#include <stdio.h>
#include <math.h>
#include <float.h>
int main() {
    int i;
    for(i=0;i<0x7FFFFFFF;i++) {
        double d = sqrt(i);
        if(fabs(d - (int)d) < DBL_EPSILON) printf("%d\n", i);
    }
}
$ time ./a.out
(略)

real    0m30.276s
user    0m30.049s
sys     0m0.070s

意外と、できるものですなぁ。

例えばこれを、競技プログラミングなどで使うには、ただの足し算で5秒というのは、あまりに遅すぎるでしょう。
けれど、こんな無茶苦茶な力技でも、たまに動かす処理や、夜の間に終わればいい処理に使うなら、それなりに現実的な時間で動きました。
とはいえ、ループの中が重くなると、一気に重くなることは目に見えているので、利用できる場面は果たして存在するのか、というくらい少ない気はしますが。

2
0
0

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
2
0