
以下のソースコードについての質問です。
---
/* 文字列を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ランキング
-
プログラムで関数は使わない方...
-
フラッシュ暗算
-
do-while文が禁止される理由
-
「Aに対するBの割合」と「Aに対...
-
有効数字について 以前質問をし...
-
C言語での引数の省略方法
-
C言語を実行すると-infが出てき...
-
数学 確率変数Xは、X=2またはX...
-
DWORDの実際の型は何でしょうか
-
ある商品のロス率を5%見込み、...
-
プログラムでの数字につく”f”の...
-
複数桁10進数の*桁目だけを抽出...
-
*をユーザーが入力した数字の数...
-
エクセルの問題です。絶対値の...
-
16進数 加算 減算 C言語
-
2÷3などの余りについて
-
Win32APIでのエディットボック...
-
異なる文字列のマッチングを、D...
-
【指数・対数】
-
Arduinoでコンパイルエラーにつ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
do-while文が禁止される理由
-
入力した数値を倍々するプログラム
-
ループを途中で抜けたいのですが。
-
C言語forループが完結した場合...
-
break文でループを一気に抜ける...
-
C言語、whileループを抜け出す...
-
入力した文字列から母音だけを...
-
プログラムで関数は使わない方...
-
For文の終了値を関数にしても問...
-
Cプログラムが終了しない
-
if文の中にfor文なのか、for文...
-
他言語で言うcontinue文
-
文字列を後ろから1文字ずつ表示...
-
if文を使わずに奇数・偶数を判断
-
整定時間
-
for文while文の無限ループの違...
-
excel VBA if文について
-
n重のfor文にするには?
-
特定の文字列が出てくるまでの...
-
VBScriptでSQLに接続し、CSV出...
おすすめ情報