アプリ版:「スタンプのみでお礼する」機能のリリースについて

以下のソースコードについての質問です。
---
/* 文字列を1文字ずつ表示して後ろから1文字ずつ消去するのを繰り返す */

#include <time.h>
#include <stdio.h>

/*--- 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);
}
---
このコード中の
while (1000.0 * (c2 - c1) / CLOCKS_PER_SEC < x);
の箇所で、整数の 1000 ではなく、実数の 1000.0 を使う意味(メリット)は
オーバーフロー対策の他に何かありますか?
ありましたら教えてください。

また、整数の1000に比べ実数の1000.0を含む計算(浮動小数点演算)に
極端に時間がかかる環境の場合、
実数を使う方がsleep関数の精度が劣るデメリットがあると思いますが、
その他に実数を使う場合のデメリットはありますか?
ありましたら教えてください。

(コードにおいて、clock_t型はunsignedと同義の場合もあれば
signed long intと同義の場合もあると思いますが、どれもありうる(処理系依存)と考えてください。
CLOCKS_PER_SECも1000や1000000の場合もあると思いますが、どれもありうる(処理系依存)と考えてください。)

A 回答 (3件)

clock_tおよびCLOCKS_PER_SECが整数型の場合、1000.0ではなく1000にすると、1秒未満は切り捨てられてしまいます。


結果として、ミリ秒単位の計測はできなくなります。

なお、clock関数が返すのはプログラムで使用したプロセッサ時間ですので、経過時間を計測するには不向きです。

この回答への補足

>clock_tおよびCLOCKS_PER_SECが整数型の場合、1000.0ではなく1000にすると、1秒未満は切り捨てられてしまいます。
>結果として、ミリ秒単位の計測はできなくなります。

とありますが、
1000 * (c2 - c1) / CLOCKS_PER_SEC
のときでもミリ秒(x)単位の計測はできると思いますが、
違うのでしょうか?

なぜなら、
1000.0 * (c2 - c1) / CLOCKS_PER_SEC の計算結果は実数に、
1000 * (c2 - c1) / CLOCKS_PER_SEC の計算結果は整数(小数以下切り捨て)になりますが、
比較対象のxは整数(unsigned long)なのでwhile文の判定結果は変わらないからです。

間違っていたらご指摘ください。

補足日時:2009/03/15 13:16
    • good
    • 0

> 1000 * (c2 - c1) / CLOCKS_PER_SEC


> のときでもミリ秒(x)単位の計測はできると思いますが、
> 違うのでしょうか?

すみません。勘違いでした。
そのとおりですね。
    • good
    • 0

>オーバーフロー対策の他に何かありますか?



無いですね。「オーバーフローしない為」に尽きます。

>CLOCKS_PER_SECも1000や1000000の場合もあると思いますが

CLOCKS_PER_SECが1000000であり、clock_tがsigned long int(signed long intは符号付き32ビットとする)と同義の場合「1000 * (c2 - c1)」は「2.147483647秒」を超えるとオーバーフローします。

つまり「引数xに与えられるのは1~2147まで」になってしまいます。

うっかり「3秒待とう」と思って「3000」などを引数に与えて呼び出すと、sleep関数から永久に抜けて来ないでしょう。

なぜなら「1000 * (c2 - c1) / CLOCKS_PER_SEC」は「-2147~2147」の間をグルグルとループするだけなので、3000以上になる事は永久に無いからです。

引数が「unsigned long x」ってなっているなら、使う人は「60秒とかも大丈夫だよな」と思って、平気で「60000」などを引数に入れて呼ぶでしょう。

>どれもありうる(処理系依存)と考えてください。

「どの処理系でもちゃんと動く」のを考えるなら「引数xに与えられるのは1~2147まで」ってのは「問題外」ですね。

「処理系に依存しないで、どの処理系でも広範囲に使える」ようにするには「1000.0と書くしかない。他に選択肢は無し」です。

この回答への補足

解説いただきありがとうございました。

今後プログラムを読む際は、
なぜ実数(あるいは整数を)使っているのかという点に
より注意を払っていこうと思います。

補足日時:2009/03/18 21:42
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!