C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[10]: 剰余の使い方ってどうやって覚えました


(過去ログ 102 を表示中)

[トピック内 25 記事 (1 - 20 表示)]  << 0 | 1 >>

■61153 / inTopicNo.1)  剰余の使い方ってどうやって覚えました
  
□投稿者/ やじゅ (1934回)-(2011/08/03(Wed) 23:57:17)
やじゅ さんの Web サイト

分類:[雑談] 

2011/08/04(Thu) 22:37:00 編集(投稿者)

雑談です。

新人の方も含めてコードレビューをしていた時に、剰余演算子(% や Mod)を使用していた処理が出てきたわけですが、
そもそも剰余演算子の使い方って、どうやって覚えたのかと疑問に思ってしまいました。

入門書の本などでも、剰余演算子って他の演算子の一部として、さらっとふれている程度で、
こういう時には、剰余演算子を使うと便利ですよって書かれたりはしていないですね。

剰余演算子(割り算の余り)は、例えば「5 % 2 = 1」は「5を2で割ると余りは1」という意味になります。
これだと、だから何で終わってしまいますが、自然数 n を3で割ると、余りは0,1,2の3個のみとなります。
つまり、0→1→2→0→1→2などと循環して処理するものがあるときに使えます。これはかなり使えるパターンです。
応用例では、i % 2 とすると、0→1→0→1となり、偶数/奇数判断に使って1行ごと背景色を変えて表を見やすくするなど。

こういうものは一回発想としてあればどんどん使えるのだが、最初に思いつかなかったら長い間思いつかないままでいるっていうことがよくある。
剰余演算子の使い方とか、そういうことが良くある例の一つだと思ってます。


私自身はベーマガなどのソースリストとか見ていて、剰余演算子を使っているけど、何でこんな事してるんだろうと思ってトレースして覚えた記憶があり
結構当時は感動したりしたものです。

みなさんは、仕事などで先輩方のソースリストを見て覚えたとか、使い方を教わったとか、なんとなく使っていたとか
どうやって覚えたのでしょうか?
引用返信 編集キー/
■61154 / inTopicNo.2)  Re[1]: 剰余の使い方ってどうやって覚えました
□投稿者/ shu (909回)-(2011/08/04(Thu) 07:35:45)
2011/08/04(Thu) 07:39:19 編集(投稿者)

No61153 (やじゅ さん) に返信

> 私自身はベーマガなどのソースリストとか見ていて、剰余演算子を使っているけど、何でこんな事してるんだろうと思ってトレースして覚えた記憶があり
> 結構当時は感動したりしたものです。
>
> みなさんは、仕事などで先輩方のソースリストを見て覚えたとか、使い方を教わったとか、なんとなく使っていたとか
> どうやって覚えたのでしょうか?
私もベーマガとかOh!○○とかで使っているのをみて数値を循環して処理するのに便利だなと思い覚えたような気がします。

ちなみに
0,1,0,1のトグルを
i = (i + 1) mod 2
でなく
i = 1 - i
で書けることを見つけたときは便利だと思いました。
これはa,bのトグルにも使えて初期値がaなら
i=a なら i = (a + b) - i => b
i=b なら i = (a + b) - i => a
となります。ちょっとそれてしまいましたmm



引用返信 編集キー/
■61156 / inTopicNo.3)  Re[1]: 剰余の使い方ってどうやって覚えました
□投稿者/ くだん (5回)-(2011/08/04(Thu) 09:56:14)
No61153 (やじゅ さん) に返信
剰余演算子の使い方に限らず、Tips みたいなものは参考になる何かを
見た時に覚える事が多いです。
…知らなくても別の書き方(多少長くなっても)ができると、改めて
調べる事ってなかなかないですからね。逆に言語の方言だと、基本
文法で書ける方が重宝する場合もありますし。
> 入門書の本などでも、剰余演算子って他の演算子の一部として、さらっとふれている程度で、
それに気付いて、よくそのような処理を書く人が覚えるだけだと思います。

剰余演算子の使い方に関しては、意識して覚えた記憶がありません。
(古くて記憶してないだけかもしれません。)
テストデータや処理の共通化を色々考えているとき(曜日ごとの処理
とかオフセットがある処理とか)に自然と「Mod でできる」と思った
ような。。。それまでに何かのソースで見てたか定かでないです。

分類すると
> なんとなく使っていたとか
かな。
引用返信 編集キー/
■61157 / inTopicNo.4)  Re[2]: 剰余の使い方ってどうやって覚えました
□投稿者/ 774RR (604回)-(2011/08/04(Thu) 10:07:28)
2011/08/04(Thu) 10:25:34 編集(投稿者)

2進数のビット演算を学んでいる際に理解したかな・・・
X and 3 == X % 4 ああ、これは剰余演算の特殊例なのだな、と。

次に rand()%100 で [0..100) の半開区間乱数を作れるな、くらいは自分で気づく人が多いかな。
実はこれだと分布が均一にならないのでダメなのだ、と自分で気づけるかどうかが、
この業界向きとか向かないとかの境界線かもしんまい。

区間が間違っていたので修正(恥)
引用返信 編集キー/
■61163 / inTopicNo.5)  Re[2]: 剰余の使い方ってどうやって覚えました
□投稿者/ やじゅ (1937回)-(2011/08/04(Thu) 13:42:52)
やじゅ さんの Web サイト
No61154 (shu さん) に返信

ご活躍いつも見ています。

> 私もベーマガとかOh!○○とかで使っているのをみて数値を循環して処理するのに便利だなと思い覚えたような気がします。

お仲間がいてうれしいです。一旦気が付けば覚えてしまいますよね。

> i = 1 - i
> で書けることを見つけたときは便利だと思いました。

これは知らなかったです、こうやって覚えていくもんだなw
引用返信 編集キー/
■61165 / inTopicNo.6)  Re[2]: 剰余の使い方ってどうやって覚えました
□投稿者/ やじゅ (1938回)-(2011/08/04(Thu) 13:49:32)
やじゅ さんの Web サイト
No61156 (くだん さん) に返信
> 剰余演算子の使い方に限らず、Tips みたいなものは参考になる何かを
> 見た時に覚える事が多いです。
> 剰余演算子の使い方に関しては、意識して覚えた記憶がありません。
> (古くて記憶してないだけかもしれません。)
> 分類すると
>>なんとなく使っていたとか
> かな。

調べものをしているうちに、違うことも気になって自然と覚えてしまう感じですね。
一緒にコードレビューしていた同僚も覚えてないって言ってました。
私自身が記憶に強烈に残っているだけなのかも。
引用返信 編集キー/
■61166 / inTopicNo.7)  Re[3]: 剰余の使い方ってどうやって覚えました
□投稿者/ やじゅ (1939回)-(2011/08/04(Thu) 13:54:54)
やじゅ さんの Web サイト
No61157 (774RR さん) に返信
> 2進数のビット演算を学んでいる際に理解したかな・・・
> X and 3 == X % 4 ああ、これは剰余演算の特殊例なのだな、と。

ビット演算子から剰余に結びつくわけか、言われてみると循環パターンになりますね。
ただ、and演算だと循環させる数値に制限が出てしまうけど。

引用返信 編集キー/
■61168 / inTopicNo.8)  Re[3]: 剰余の使い方ってどうやって覚えました
□投稿者/ チョリ (1回)-(2011/08/04(Thu) 14:02:17)
No61165 (やじゅ さん) に返信

例えばhtml形式の文字列を生成するとき、n列のテーブルに、左からm個の画像を埋める場合、
(最後の行の空セルを調整するために)剰余計算をよく使いました。
もっといい方法があるのかもしれませんが、わたしが最初に思いついたのはこの方法でした。
引用返信 編集キー/
■61172 / inTopicNo.9)  Re[4]: 剰余の使い方ってどうやって覚えました
□投稿者/ くり太郎 (38回)-(2011/08/04(Thu) 14:27:21)
くり太郎 さんの Web サイト
僕は mod の説明とともにサンプルをみたので、剰余を上手に使ってるという感動みたいなものはありませんでしたね。
日付計算ライブラリーを自作したとき、曜日の算出で使ったりしました。

ちなみに 0 と 1 を交互にとる場合は、引き算で次のようにする方が多いですかね〜

n = 1 - n;

引用返信 編集キー/
■61183 / inTopicNo.10)  Re[1]: 剰余の使い方ってどうやって覚えました
□投稿者/ キャッサバ (1回)-(2011/08/04(Thu) 19:05:34)
No61153 (やじゅ さん) に返信
> 自然数 n を2で割ると、余りは0,1,2の3個のみとなります。

余りは0,1の2個のみですよね。
引用返信 編集キー/
■61184 / inTopicNo.11)  Re[2]: 剰余の使い方ってどうやって覚えました
□投稿者/ キャッサバ (2回)-(2011/08/04(Thu) 19:09:19)
書き込み途中で送信してしまいました。

小生もチョリソさんに似ていますが、ビットマップデータのByte配列のX座標を求めたりするような
マトリクス計算で使います。
引用返信 編集キー/
■61186 / inTopicNo.12)  Re[2]: 剰余の使い方ってどうやって覚えました
□投稿者/ やじゅ (1941回)-(2011/08/04(Thu) 22:38:10)
やじゅ さんの Web サイト
2011/08/04(Thu) 22:45:10 編集(投稿者)

No61183 (キャッサバ さん) に返信
> ■No61153 (やじゅ さん) に返信
>>自然数 n を2で割ると、余りは0,1,2の3個のみとなります。
> 余りは0,1の2個のみですよね。

ありがとうございます、訂正しました。

チョリさんも、キャッサバさんも剰余を使うケースを
どうやって思いついたのかなと。

この時に剰余を使えるって、何故思いついたのか?
その前に、循環することが自然と分かっていたのはどこかで見たからでしょうか。
引用返信 編集キー/
■61188 / inTopicNo.13)  Re[5]: 剰余の使い方ってどうやって覚えました
□投稿者/ やじゅ (1942回)-(2011/08/04(Thu) 22:54:42)
やじゅ さんの Web サイト
No61172 (くり太郎 さん) に返信
> 僕は mod の説明とともにサンプルをみたので、剰余を上手に使ってるという感動みたいなものはありませんでしたね。

みなさんも、やはりそんな感じなんだろうな。

> 日付計算ライブラリーを自作したとき、曜日の算出で使ったりしました。

業務系アプリだと、カレンダー作成や帳票などで5明細ごとに線を引くなどに使ったりして覚える感じかな。
1行ごと背景色を変えるってのは、最近のグリッドではプロパティに備わってたりするから意識しないかも。

引用返信 編集キー/
■61189 / inTopicNo.14)  Re[1]: 剰余の使い方ってどうやって覚えました
□投稿者/ kobusi (2回)-(2011/08/04(Thu) 23:55:29)
No61153 (やじゅ さん) に返信

>そもそも剰余演算子の使い方って、・・・
面白い話題ですね!

まだCase文のないアセンブラの頃だったので、剰余演算はよく使いました。

(例) n個のCase文
 初心者がよくやる(cmp,je)の羅列!(私もやっちゃいましたが)

 先輩に定番のコーディング教えられ、目から鱗!
(概略ですが・・)
adr = value % n
jmp JMP_TBL[adr]

単純ですが上記にShiftやbit演算を応用したり、よりリカーシブな
プログラムが書けるようになりました。

C言語になってからは、(リングバッファ)はよく使いましたね。

 ・・・・
 buffer[p} = newdata
 p = (p + 1) % n
 ・・・・

最近の開発環境・言語では、直接アドレス操作することも少ないでしょが・・。

nで剰余しておけば、「nを超えることのない世界で処理できる」って、結構、有用じゃないかな?

何故か久しぶりにプログラム始めた頃を思い出したので投稿してみました。



引用返信 編集キー/
■61190 / inTopicNo.15)  Re[3]: 剰余の使い方ってどうやって覚えました
□投稿者/ キャッサバ (3回)-(2011/08/05(Fri) 05:46:19)
No61186 (やじゅ さん) に返信

> チョリさんも、キャッサバさんも剰余を使うケースを
> どうやって思いついたのかなと。
>
> この時に剰余を使えるって、何故思いついたのか?
> その前に、循環することが自然と分かっていたのはどこかで見たからでしょうか。

言語をVBと仮定して、例えば、インデックスが0から始まるa()という配列があったとして、
これを列数がmで、左上の座標が(0, 0)であるマトリクスに展開する場合、a(n)の座標は
X座標→n÷mの余り(n Mod m)
Y座標→n÷mの商(n \ m)
で求められるなと思ったので、そういえば、剰余と商の演算子があったな、使ってみよう、ということで使った次第です。
なので、この場合は商演算子(いわゆる\演算子)も使っています。

例えば、5列のマトリクスの場合、a(7)の座標は、(7 Mod 5, 7 \ 5) = (2, 1)となり、
以下のマトリクスの座標の左上を(0, 0)とした場合に、このマトリクスの7の座標の位置に一致します。

 0 1 2 3 4
 5 6 7 8 9
 A B C D E

チョリさんが言うように、他にもっといい方法があるのかもしれませんが、このやり方を思いつくことで精いっぱいです。

あと、少なくとも、その言語で使用できる演算子は必ず確認しますので、これらの演算子を覚えていたのでしょう。
例えば、四則演算以外の演算子記号(例えばべき乗)は言語によって表現が異なったりしますので。
引用返信 編集キー/
■61191 / inTopicNo.16)  Re[2]: 剰余の使い方ってどうやって覚えました
□投稿者/ shu (912回)-(2011/08/05(Fri) 07:51:52)
剰余にちなんで割りと最近知ったこと

言語依存性を少なくするために、剰余の計算をMathのメソッドで処理してみようと
思ったことがあり、IEEERemainderは剰余を計算するらしいということで試したのですが
とんでもない仕様であることが分かったことがありました。

        Dim a = Math.IEEERemainder(5, 2)
        Dim b = Math.IEEERemainder(7, 4)
        Dim c = 0
        Dim d = Math.DivRem(7, 4, c)

        Console.WriteLine(String.Format("a = {0}", a))
        Console.WriteLine(String.Format("b = {0}", b))
        Console.WriteLine(String.Format("c = {0}", c))
        Console.WriteLine(String.Format("d = {0}", d))

この結果ですが、
a = 1
b = -1
c = 3
d = 1

となります。余り-1って・・・。でもこれはこの関数の仕様からすると正しいのです。
7 / 4 = 1.75 で 端数処理すると 2となります。
※端数処理は偶数丸めです。1.5なら2、4.5なら4になるという計算です。
7 -  2 * 4 = -1 と計算するのがIEEERemainderの仕様のようです。これはdouble用の計算なのでそんな
処理になっているんですかね。
7個のおかしを4人で分けるには1個足りないから、もう1つ持ってきて分けようみたいな感じですね。
DivRemを使うと普通に3が返ってきます。

引用返信 編集キー/
■61192 / inTopicNo.17)  Re[3]: 剰余の使い方ってどうやって覚えました
□投稿者/ 774RR (605回)-(2011/08/05(Fri) 08:47:13)
http://seclan.dll.jp/c99d/c99d05.htm
C89/C++ では負整数の商と剰余の挙動が変則的な処理系を許しているので、剰余演算には注意が必要。
ISO/IEC 14882:1998 5.6-4
JIS X3014:2003 (ISO/IEC 14882:2003)

-1 / 2 は 商0剰余-1 なのか 商-1剰余1 なのか、処理系定義。

C99 で修正が入ったが C++ は修正されていない。
JIS X3010:2003 6.5.5
整数商の結果は0方向への切捨てであると明記
かつ (a/b)*b + (a%b) = a でなければならないので、剰余の符号は自動的に決まる

引用返信 編集キー/
■61194 / inTopicNo.18)  Re[4]: 剰余の使い方ってどうやって覚えました
□投稿者/ チョリ (2回)-(2011/08/05(Fri) 09:31:33)
確かに、商と剰余を負数で使うことを考えたことがありませんね。
もっとも、商(整数のみ)と剰余(余り)は、「40個のみかんを6人で分けた場合...」のような使い方が本来の姿であると思いますので、
おそらく、負数の商・剰余については、数学的な拡張定義はないのではないかと思います。

>キャッサバさん
マトリックスについては私と全く同じ考えですね。
ちなみに私はチョリソではありません(笑)
引用返信 編集キー/
■61195 / inTopicNo.19)  Re[1]: 剰余の使い方ってどうやって覚えました
□投稿者/ 魔界の仮面弁士 (2288回)-(2011/08/05(Fri) 09:59:53)
2011/08/05(Fri) 10:05:09 編集(投稿者)

No61153 (やじゅ さん) に返信
> 新人の方も含めてコードレビューをしていた時に、剰余演算子(% や Mod)を使用していた処理が出てきたわけですが、
> そもそも剰余演算子の使い方って、どうやって覚えたのかと疑問に思ってしまいました。

元ネタからは少々外れるのですが、社内研修で算術演算について教える際に、
VB 使いに注意しているのが、演算時には「型」を意識する必要がある、という点。

「7 Mod 3.5」を計算した場合、VB6 だと 3 を返し、VB.NET だと 0.0 を返します。


VBA/VBScript を含む旧VBでは、Mod 演算は常に整数で処理されるため、
演算前に銀行丸めによって 7 Mod 4 へと変換され、余りが 3 と算出されます。
一方、VB.NET においては実数での剰余計算がサポートされているため、
7.0 は 3.5 で割り切れるとみなされ、0.0 という結果を返します。

そして \ 演算子については、VB6 も VB.NET も整数のみのサポート。
いずれも Long 型に変換されて処理されるため、7 を 4 で割ることになり
求められる商は共に 1 になります。7.0 ÷ 3.5 で商「2.0」剰余「0.0」とはなりません。


なので、演算処理を行う際には、それぞれの項の型が何になっていて、
演算時にはそれらがどの型で処理されるのかを意識する必要がある、と。


これらと同様に、/ 演算子も型によって振る舞いが微妙に異なりますね。
さらに言えば、VB と C# とではルールが異なりますし。
(整数同士を / 演算した場合、VB は Double で返し、C# は整数で返すなど)
引用返信 編集キー/
■61196 / inTopicNo.20)  Re[5]: 剰余の使い方ってどうやって覚えました
 
□投稿者/ 774RR (606回)-(2011/08/05(Fri) 10:20:09)
中学校1年生の教科書によると 乗除法において
・同符号の2数の乗除 = 絶対値の積・商に、正の符号をつける
・異符号の2数の乗除 = 絶対値の積・商に、負の符号をつける
と教えているようですな(結果的に0方向への切捨てとなる)

# VB 系のその辺の仕様の違いって C++ 屋には恐怖っすね・・・
引用返信 編集キー/

次の20件>
トピック内ページ移動 / << 0 | 1 >>

管理者用

- Child Tree -