割り算と余りを一度に
Pythonには商と余りを一度に求めるdivmodっていう関数がある。
>>> divmod(10, 3) (3, 1)
C言語にはないのかなと思って探してみると、やっぱりあった。divって関数だ。
div_t res; res = div(10, 3);
しかしCRTの実装(VC\crt\src\div.c)を見てみると、
div_t __cdecl div ( int numer, int denom ) { div_t result; result.quot = numer / denom; result.rem = numer % denom; return result; }
うわー、思いっきり2回に分けて計算してるしー。
でもね、実際にコンパイルしてみると……
CDQ IDIV DWORD PTR SS:[EBP+C]
1回にまとめられてる。VCの最適化ってすごいな。
ところで、IDIVの1つ前にCDQが置かれている。こいつが気になった。解説はここにあるが、読んでもよくわからなかった。実際にデバッガで実行してみると、EDX を 0 や F で埋めていたので、どうやら符号拡張に関わる命令らしい。
IDIVの説明によれば、どうも x86 の IDIV は「64ビット割る32ビット」をやるらしく、そのため数字のビット長を拡大する必要があって、それが符号拡張処理ってことか。