clock関数

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら

clock関数

#1

投稿記事 by » 16年前

こんにちは。いつもお世話になっています。
C言語は初心者で、現在テキストを参考にしながら進めています。
WindowsのVistaを使っています。

今回の質問は、clock関数を用いて、xミリ秒経過するのを待つ関数に関してです。
int sleep( unsigned long x )
{
    clock_t c1 = clock(), c2;
    do {
        if ( ( c2 = clock() ) == ( clock_t ) -1 ) {
            return ( 0 );
        }
    } while ( 1000.0 * ( c2 - c1 ) / CLOCKS_PER_SEC < x );
    return ( 1 );
}
・( clock_t ) -1 というのはclock_t型でキャストされた-1とテキストにあったのですが、-1はどういう意味があるのでしょうか?よろしくお願いします。

御津凪

Re:clock関数

#2

投稿記事 by 御津凪 » 16年前

clock 関数の仕様では、関数が失敗すると -1 を返します。
上記のコードの場合、 clock 関数の戻り値を取得した値( c2 )と比較し、一致していれば処理が失敗したと判断しています。

Re:clock関数

#3

投稿記事 by » 16年前

解答ありがとうございます。

すいません、もう一つ質問がありました。
・どうして、1000.0を掛けるのでしょうか?

御津凪

Re:clock関数

#4

投稿記事 by 御津凪 » 16年前

clock 関数は文字通りクロック時間を返すので、 CLOCKS_PER_SEC を使って秒単位に変換します。
second = ( c2 - c1 ) / CLOCKS_PER_SEC; // 秒単位に変換
今回必要としているのはミリ秒なので、
一度経過クロック時間に 1000 を掛けてから CLOCKS_PER_SEC で割ることにより、
単位をミリ秒に変換しています。
milli_second = 1000 * ( c2 - c1 ) / CLOCKS_PER_SEC; // ミリ秒単位に変換
ちなみに上の式の計算順序では小数点以下は計算に影響がないため、
1000 にしても計算結果は変わりません。

Re:clock関数

#5

投稿記事 by » 16年前

めっちゃ、理解出来ました。
ありがとうございました。

toyo

Re:clock関数

#6

投稿記事 by toyo » 16年前

xの値によっては1000 * ( c2 - c1 )がclock_t型をオーバーフローする可能性を考えてdouble型にしているのでは
CLOCKS_PER_SECが1000000ならその可能性も高くなりますし

御津凪

Re:clock関数

#7

投稿記事 by 御津凪 » 16年前

> xの値によっては1000 * ( c2 - c1 )がclock_t型をオーバーフローする可能性を考えてdouble型にしているのでは

そういえば CLOCKS_PER_SEC の値を見ていませんでした。
1000000 なら、2147 ミリ秒を超えたらオーバーフローしますね。
(clock_t が long 型の場合)
milli_second = (unsigned long)(1000ULL * ( c2 - c1 ) / CLOCKS_PER_SEC);
で、 64bit で計算しても回避可能ですね。

Re:clock関数

#8

投稿記事 by » 16年前

>1000000 なら、2147 ミリ秒を超えたらオーバーフローしますね。
これって、どういう意味ですか?

御津凪

Re:clock関数

#9

投稿記事 by 御津凪 » 16年前

32bit符号付き(long型)の場合、 1000000 * 2147 では、
2147000000 と正しく計算されるのですが、
1000000 * 2148 となると、
-2146967296 となってしまいます。(これがオーバーフロー)

これは、最初に提示されている sleep 関数で 1000.0 を 1000 にした場合
0 ~ 2147 ミリ秒までしか正しく処理されないということになります。
もし、2148 以上を指定した場合は、オーバーフローで負数になっているため、
2148 ミリ秒までしか待ってくれません。

そのため、 2147 ミリ秒以上待つ可能性がある場合は提示されている関数のままの状態か、
経過時間の計算時に 64bit 整数として計算するように直すといいと思います。

閉鎖

“C言語何でも質問掲示板” へ戻る