最大値と最小値の間を循環する変数
最大値と最小値(ゼロ)の間を循環する変数counterを考えています。
以下が私が考えたコードです。
if (plus) {
counter++;
if (counter > MAX)
counter = MIN;
} else if (minus) {
counter--;
if (counter < MIN)
counter = MAX;
} else {
;
}
これで一応動くのですが、いかにもダサイので、もっと上手い方法が無いかと悩んでいます。
例えば、counter %= (MAX + 1) とでもすれば、加算の場合は上手くいく(?)のですが、減算の場合は上手くいきません。
何か良い方法は無いでしょうか。
No.5ベストアンサー
- 回答日時:
MIN≦counter≦MAXで循環させるのに、Xで割った余りを使いたいのなら、 0~X-1の範囲になるように変形する必要があります。
全辺から MINを引くと
0≦counter-MIN≦MAX-MIN
なので、 counter - MIN を MAX-MIN +1で割った余りを使うことになります。
引いたMINは改めて足せば元の範囲になります。
加算
counter = MIN + ( ( counter - MIN ) +1 ) % (MAX - MIN + 1) ;
減算:負の%演算はややこしいので、1周期分加えて正の値にする
counter = MIN + ( ( counter - MIN ) - 1 + (MAX - MIN + 1)) % (MAX - MIN + 1) ;
自分で書いといてなんですが、正直、わかりずらいです。
それに、整数演算の中では、割り算はもっとも時間のかかるものです。その意味ではこの方法は効率的とは言えません。
値の変化が任意(+50とか*15とかする)なら、割り算を使うのが効果的かもしれませんが。
私が作るなら、この質問にあるようなif文を使うか、三項演算子を使うか、ですね。
加算
counter = (counter == MAX) ? MIN : (counter + 1) ;
減算
counter = (counter == MIN) ? MAX : (counter - 1) ;
御回答ありがとうございます。
なるほど、三項演算子という手段がありましたか。
これが総合的に見て一番優れている気がします。
割り算を使用する方法も、適用するかどうかは別として、自力で考えつく位にはなりたいものです。
No.6
- 回答日時:
とりあえず、最後のelseは不要ですよね。
それと、plus と minus はそれぞれ個別でbool定義されて
いますが、それは必須でしょうか? 無駄なような気が……?
既に色々な手法が提案されていますので、自分は「その他案」を。
例えばint型配列にて{ 1, -1} を定義すれば、以下の形が可能です。
c が 0 ならインクリメント、1 ならデクリメントされるという事ですね。
counter += tbl[c];
if (counter < MIN) counter = MAX;
if (counter > MAX) counter = MIN;
判り易いので自分はこんな風に書く時もあるのですが、これを
人にオススメしていいのかは判りません……(^^;
御回答ありがとうございます。
質問の本筋以外は、例を示す為に適当に書いたものなので、深く突っ込まないで頂けるとありがたいです。
この方法も面白いですね。
ややトリッキーな感じなので、個人で書くプログラム以外では使用しづらいですが、知識として蓄えておきます。
No.4
- 回答日時:
FIFO(循環バッファ)のようなものであれば
バッファの大きさを2の階乗にすると
char buffer[256];
unsigned char read_p, write_p;
//書き込み
buffer[write_p++] = data;
//読み込み
if (read_p != write_p)
data = buffer[read_p++];
と書けます。バッファが128バイトであれば
char buffer[2^7];
unsigned int read_p, write_p;
//書き込み
buffer[write_p++] = data;
write_p &= (sizeof(buffer) - 1);
//読み込み
if (read_p != write_p) {
data = buffer[read_p++];
read_p &= (sizeof(buffer) - 1);
}
となり、if文が省略できて高速です。
またCPUによっては、バッファのサイズが256でもインデックスをunsigned intにして128と同様に記述した方が速い場合があります。
バッファの定義をアセンブラで記述して、アライメントを2の階乗に揃えた場合、インデックスではなくてポインターが使用できるのでより高速になります。
No.3
- 回答日時:
正直なところ, 今のコードのままでいいんじゃないの? 無駄に凝るよりシンプルでいいと思うんだけどなぁ.... まあ「全ての実行パスで所要クロック数を統一したい」というならそれはそれでいいけど, かえって面倒な感じしかしない.
ちなみに「MAX 以上 MIN 以下の間を動く」んだったら, counter %= MAX+1; じゃダメだよね.
御回答ありがとうございます。
確かに、実際の現場では、わかりやすさを優先してこのように書くかもしれません。
ただ、知っているのと知らないのとでは大違いなので、質問自体は意義があると思いたです。
No.2
- 回答日時:
plus
minus
MAX
MIN
の意味がわかりませんので、一応動くといわれましても
にわかに信じがたいです。
この回答への補足
御回答ありがとうございます。
質問とは直接関係ない部分だと思ったので、質問をシンプルにするつもりで省略してしまいました。
plus・minusには特に意味はなく、単に真になったらインクリメントもしくはデクリメントするといった程度の意味です。
MINとMAXは最小値と最大値で、counterを0~9の間で循環させたいなら、MINは0でMAXは9になります。
適当なところでdefineされているイメージです。
以上、捕捉になっているでしょうか。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# c言語 プログラムのエラー 1 2023/02/11 20:31
- 英語 提示分の"with"の使い方等について 1 2022/08/23 10:40
- PHP PHPでユーザー情報を入力して簡易ログイン機能をつくってみたのですが 1 2023/05/29 08:51
- JavaScript ソースコードのいじる場所が分かりません。 1 2022/12/23 02:06
- C言語・C++・C# C言語のエラーについて 2 2022/07/11 13:56
- 英語 英語についての質問です。 We have learned a lot about when and 1 2022/11/21 17:58
- Excel(エクセル) VBAで “:” を含むセルの特定 2 2023/05/11 16:30
- PHP PHP MySql ページング 2 2022/09/20 06:38
- Visual Basic(VBA) 3つのプロシージャをまとめたら実行時エラー発生で対応不能 6 2022/05/17 01:47
- Excel(エクセル) エクセル開いたらウィンドウがでました 2 2023/03/28 16:24
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
TOEFLでadhdすぎて
-
C言語をコンパイルするとコンピ...
-
こんなことてしますか??
-
どちのほうがすきですか?
-
Notepad++の関数リスト表示の変...
-
あなたは、Excelはどうやって学...
-
これなにがちがうんですか??
-
ArduinoのジャイロモジュールMP...
-
[C言語]fputsとfprintfの違い
-
システムエンジニアの適正について
-
Stuck
-
ArduinoでMouse関数を使用して...
-
Linuxでの開発環境構築や設定の...
-
c言語
-
プログラミング言語の制作方法...
-
C++でデスクトップGUIアプリ開...
-
mallocについて
-
C言語 配列と関数の練習問題
-
WindowsのCapsLock(キャップス...
-
Notepad++の関数リスト表示でC...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
write downとfill outの違いを...
-
奇数・偶数の区別をプログラミング
-
シリアル通信プログラミングで...
-
最大値と最小値の間を循環する変数
-
OpenSSLのSSL_write()をタイム...
-
忘れないうちに書き留めておき...
-
C言語について。
-
私は、もっと早くお祝いメッセ...
-
HTMLの値の渡し方について質問...
-
aspxでIFみたいなことがしたい
-
遷移先のURLにパラメータを表示...
-
ACCESSのレポートの表示...
-
ASP.netで、CheckBoxListのSele...
-
キリンビール(晴れ風)どうでし...
-
SELECTボックスの内容を動的に...
-
<br>が文字列で出力されてしま...
-
フォームのtextareaにnl2brを使...
-
改行したいのですが
-
javascriptで結果表示テキスト...
-
テキストボックスにマクロでメ...
おすすめ情報