
以下のソースコードについての質問です。
---
/* 文字列を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件)
- 最新から表示
- 回答順に表示
No.3
- 回答日時:
>オーバーフロー対策の他に何かありますか?
無いですね。「オーバーフローしない為」に尽きます。
>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と書くしかない。他に選択肢は無し」です。
この回答への補足
解説いただきありがとうございました。
今後プログラムを読む際は、
なぜ実数(あるいは整数を)使っているのかという点に
より注意を払っていこうと思います。
No.2
- 回答日時:
> 1000 * (c2 - c1) / CLOCKS_PER_SEC
> のときでもミリ秒(x)単位の計測はできると思いますが、
> 違うのでしょうか?
すみません。勘違いでした。
そのとおりですね。
No.1
- 回答日時:
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文の判定結果は変わらないからです。
間違っていたらご指摘ください。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# プログラミングの授業の課題です 1 2023/01/17 22:15
- C言語・C++・C# C言語 3 2022/10/04 15:07
- C言語・C++・C# 宣言する関数の形が決まっている状態で、 str1とstr2の文字列をこの順に引っ付けてstrに保存し 2 2022/05/30 18:21
- Excel(エクセル) capeofdragonと申します Excel2016を使っておりまして 半角又は全角の任意文字列が 2 2022/10/31 13:51
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- C言語・C++・C# このプログラミングの問題を教えて欲しいです。 キーボードから整数kを入力し、kが配列aの中に何個存在 2 2022/12/19 22:50
- Excel(エクセル) 時間差を求めるマクロコードを教えてください。 4 2022/05/17 18:22
- C言語・C++・C# 変数のスコープ 5 2023/05/27 17:50
- C言語・C++・C# C言語階乗の総和を求める 2 2023/03/04 23:31
- Visual Basic(VBA) サブフォルダ(データ)にある複数の.xlsxファイルのSheet3のA2セルの値で01から左側をB2 2 2022/08/14 15:46
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
整定時間
-
ループを途中で抜けたいのですが。
-
入力した数値を倍々するプログラム
-
最大時間計算量を求める問題な...
-
While文の終わりにセミコロンが...
-
H8/3048マイコンAD/DA変換について
-
プログラムの『軽い』と『重い...
-
Matlabを使った心理学実験
-
他言語で言うcontinue文
-
if文の中にfor文なのか、for文...
-
C++ DirectX カーソルの移動処...
-
do-while文が禁止される理由
-
プログラムで関数は使わない方...
-
VBScriptでSQLに接続し、CSV出...
-
Excel VBAで年度をまたぐ期間の...
-
C言語forループが完結した場合...
-
For文の終了値を関数にしても問...
-
strtokを使用したループ内でのs...
-
strstr()関数の実装内容について。
-
C言語、whileループを抜け出す...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
do-while文が禁止される理由
-
ループを途中で抜けたいのですが。
-
Excel VBAで年度をまたぐ期間の...
-
C言語forループが完結した場合...
-
UWSCにてある一定の動作を無限...
-
入力した文字列から母音だけを...
-
excel VBA if文について
-
プログラムで関数は使わない方...
-
C++のvolatileについて
-
入力した数値を倍々するプログラム
-
For文の終了値を関数にしても問...
-
break文でループを一気に抜ける...
-
Delphiで・・・
-
if文の中にfor文なのか、for文...
-
for文while文の無限ループの違...
-
PIC のプログラムについて ど...
-
他言語で言うcontinue文
-
PAD図の書き方
-
C言語、whileループを抜け出す...
-
clock関数を利用した時間計測法...
おすすめ情報