この人頭いいなと思ったエピソード

C言語についてですが、
整数の除算を行うときに、商と剰余を同時に求めることは可能なは
ずなので、1回の演算で両方知りたいのですが、c = a / b;だと商
だけ、d = a % b;だと剰余だけしか分からないです。
1回の演算で両方得たい場合はどう記述すればいいでしょうか?

A 回答 (8件)

stdlib.hのdiv()ではダメなのですか?


商と余からなる構造体 div_tを返します。

この回答への補足

ありがとうございます。
うちのstdlibにも同じ定義がありました。
さっそく試してみます。

補足日時:2005/02/09 12:15
    • good
    • 0
この回答へのお礼

ありがとうございました。
おかげで処理時間を短縮できました。

お礼日時:2005/02/11 08:13

>商と剰余を同時に求めることは可能なはずなので


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..なら除算しないでシフトするだけかと思われます。
    • good
    • 2
この回答へのお礼

ありがとうございました。

お礼日時:2005/02/11 08:17

下記のコードを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);
    • good
    • 0
この回答へのお礼

ありがとうございました。

お礼日時:2005/02/11 08:17

C++Builderの実装を見たんですが、div()はアセンブラで実装されてますね。


速そう。
    • good
    • 0
この回答へのお礼

ありがとうございました。

お礼日時:2005/02/11 08:01

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回の演算を行う方法で十分かと思いますが・・・。
    • good
    • 0
この回答へのお礼

ありがとうございました。

お礼日時:2005/02/11 08:01

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回呼ばれて演算時間
が浪費されているのをどうにかできないかなという
のが今抱えている本題です。

補足日時:2005/02/09 12:18
    • good
    • 0
この回答へのお礼

ありがとうございました。

お礼日時:2005/02/11 08:00

残念ながら C でそのような書き方はできません。



機械語で書けば 1 回でできるのに C ではずいぶん無駄なことをしないといけないと私も思います。

ただし、できのよいコンパイラであれば 1 回だけ除算をして結果の商と剰余を c と d に格納するような機械語に落としてくれます。
    • good
    • 0
この回答へのお礼

ありがとうございました。

お礼日時:2005/02/11 08:00

アセンブラなら可能ですが、Cなどの高級言語では左辺は一つしか取れないので、


1回の演算で商と剰余を同時に両方求めるというのは、不可能だと思います。
    • good
    • 0
この回答へのお礼

ありがとうございました。

お礼日時:2005/02/11 08:00

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています


おすすめ情報