- ベストアンサー
商と剰余を同時に求める(C言語)
C言語についてですが、 整数の除算を行うときに、商と剰余を同時に求めることは可能なは ずなので、1回の演算で両方知りたいのですが、c = a / b;だと商 だけ、d = a % b;だと剰余だけしか分からないです。 1回の演算で両方得たい場合はどう記述すればいいでしょうか?
- みんなの回答 (8)
- 専門家の回答
質問者が選んだベストアンサー
stdlib.hのdiv()ではダメなのですか? 商と余からなる構造体 div_tを返します。
その他の回答 (7)
- mssine
- ベストアンサー率24% (38/156)
>商と剰余を同時に求めることは可能なはずなので x86では可能ですが、それが出来ないプロセッサもあります。(TRONチップがそうだったような。。) Cは汎用言語なので、どんなプロセッサでも同じソースで動かなければならないので、こういう風になっているんだと思います。 x86環境ならインラインアセンブラで void div(int a, int b, int *c, int *d) { _asm { mov eax, a mov edx, 0 idiv b mov ebx, [c] mov ecx, [d] mov [ebx], eax mov [ecx], edx } } main() { int a,b,c,d; div(a, b, &c, &d); } #7様 除数と被除数の両方が定数で無い場合、最適化しても除算は2回になってしまうと思うのですが。。 除数が2,4,8..なら除算しないでシフトするだけかと思われます。
お礼
ありがとうございました。
- yasuch
- ベストアンサー率41% (27/65)
下記のコードをMSVC 6.0でコンパイルしてみたんですが アセンブラ出力で確認したところ、 最適化無し(/Od)では除算は2回 速度最適化(/O2)では除算は1回 でしたの。 自分のコンパイラでも確認して、あとはコンパイラの最適化に 任せてはいかがでしょうか。 int r = (int)rand(); int quot = r/3; int rem = r%3; printf("%d, %d\n", quot, rem);
お礼
ありがとうございました。
- qKAZp
- ベストアンサー率47% (71/148)
C++Builderの実装を見たんですが、div()はアセンブラで実装されてますね。 速そう。
お礼
ありがとうございました。
- tatsu99
- ベストアンサー率52% (391/751)
1回の演算でできないのは、他の方々が言われているとおりです。 どうしても、1回でやりたい場合は、#3のかたのように関数を自作することになりますが、この程度の関数なら、マクロで実装することもできます。 ------------------------------ //商と余りを同時に求める #include <stdio.h> #define MYDIV(HIJOSU,JOSU,SHO,AMARI)\ {\ SHO = HIJOSU / JOSU;\ AMARI = HIJOSU % JOSU;\ } void main(void){ int sho1; int sho2; int amari1; int amari2; MYDIV(10,4,sho1,amari1) MYDIV(10,-3,sho2,amari2) printf("商=%d 余り=%d\n",sho1,amari1); printf("商=%d 余り=%d\n",sho2,amari2); } ------------------------------- MYDIVのパラメータは被除数、除数、商、余りになっています。 被除数、除数を与えると商、余りが求められます。 商と余りを同時に必要とする演算が、ソースの中に大量に存在する場合は、このようなマクロを使用すると視認性は良くなります。 通常は、2回の演算を行う方法で十分かと思いますが・・・。
お礼
ありがとうございました。
- ysk6406
- ベストアンサー率40% (237/589)
C の式は、一度に2つの変数に値を代入するのは不可能です。(Perl ならできますが…) なので、どうしても商と剰余を同時に求めたいなら、次のような構造体を用意して、この構造体形式で値を返す(また、参照渡しでもいいのですが)関数でも書くしかないのではないでしょうか? struct warizan { int sho; int amari; }; struct warizan x; struct warizan div(int a, int b) { static struct warizan res; res.sho = a / b; res.amari = a % b; return (res); } main() { x = div(10, 3); }
お礼
ありがとうございました。
補足
説明不足で申し訳ありません。 時間短縮のために除算関数が2回呼ばれて演算時間 が浪費されているのをどうにかできないかなという のが今抱えている本題です。
- tttt23
- ベストアンサー率25% (76/303)
残念ながら C でそのような書き方はできません。 機械語で書けば 1 回でできるのに C ではずいぶん無駄なことをしないといけないと私も思います。 ただし、できのよいコンパイラであれば 1 回だけ除算をして結果の商と剰余を c と d に格納するような機械語に落としてくれます。
お礼
ありがとうございました。
- yasuch
- ベストアンサー率41% (27/65)
アセンブラなら可能ですが、Cなどの高級言語では左辺は一つしか取れないので、 1回の演算で商と剰余を同時に両方求めるというのは、不可能だと思います。
お礼
ありがとうございました。
お礼
ありがとうございました。 おかげで処理時間を短縮できました。
補足
ありがとうございます。 うちのstdlibにも同じ定義がありました。 さっそく試してみます。