// http://t...content-available-to-author-only...h.net/test/read.cgi/tech/1354393458/861
#include <stdio.h>
#include <sys/time.h>

// 戻り値   = -1 : 入力値が負
//            -2 : 結果が桁あふれする
// メモ     = ・計算結果が 31bit-1 = 2147483647 までのものをサポート
int f_31bit(int d)
{
    int dd;
    int k;
    int n;                      // 桁数
    int zero;                   // ゼロ個数
    int res;                    // 結果

    // check
    if (d < 0) {
        return -1;
    }
    if (d < 10) {
        return d;
    }
    // 桁数数えなど
    dd = d / 10;
    k = 1;
    for (n = 1; dd >= k; n++) {
        k *= 10;
    }

    // 0以外をresにいれながら0を数える
    res = zero = 0;
    for (; n > 0; n--) {
        if (d >= k) {
            res = res * 10 + d / k;
        } else {
            zero++;
        }
        d %= k;
        k /= 10;
    }

    // 0を付け加える
    for (; zero > 0; zero--) {
        if (res > 214748364) {  // resが次で10倍されたら桁あふれする
            return -2;
        }
        res *= 10;
    }

    // 終了
    return res;
}

int main()
{
    int v;                      // 値
    v = 20010307;
//    v = 1020304050;
//    v = 2147483647;             // 良い
//    v = 2000000014;             // 良い
//    v = 2000000020;             // ダメ (計算結果の 2200000000 は 2147483647(== 2^31-1)を越える)
    int ex = 100000;            // 実行回数
    int count = 10;             // 計測回数
    int res;
    int i, j;
    struct timeval s, e;
    double sum;                 // 結果

    printf("f_31bit(%d);を%d回実行する時間の計測を%d回し、平均時間を出す\n", v, ex, count);
    if (0 <= (res = f_31bit(v))) {  // 試しに実行
        sum = 0.0;
        for (j = 0; j < count; j++) {
            gettimeofday(&s, NULL);
            for (i = 0; i < ex; i++) {
                res = f_31bit(v);
            }
            gettimeofday(&e, NULL);
            sum += (e.tv_sec - s.tv_sec) + (e.tv_usec - s.tv_usec) / 1000000.0;
        }
        printf("result = %d, time = %fms\n", res, 1000.0 * sum / ((double) count));
    } else if (-1 == res) {
        printf("入力値が負\n");
    } else if (-2 == res) {
        printf("結果が 2147483647 を越える\n");
    }

    return 0;
}
