C++でb[bit]の非負整数の除算に関する質問

このQ&Aのポイント
  • C++で、b[bit]の非負整数を表現した場合の除算に関する質問です。
  • 非負整数aをb[bit]の非負整数Dで割った商と余りを求める方法についての質問です。
  • C++で計算する際にループ処理を含まないで、(m0*2^b)/Dと(m0*2^b)%Dを求める方法が知りたいです。
回答を見る
  • ベストアンサー

C++で、b[bit]の非負整数(例えば、unsigned long)

C++で、b[bit]の非負整数(例えば、unsigned long)2つa0,a1を用いて、2b[bit]の非負整数を表現した場合の除算に関する質問です。 非負整数 a=a0*2^b+a0 を b[bit]の非負整数 D(≠0) で割った、商と余りを求めたいのですが、例えば次のように求めようとします、 d0 = a0/D. m0 = a0%D. d1 = (m0*2^b+a1)/D = (m0*2^b)/D + a1/D m1 = (m0*2^b+a1)%D = (m0*2^b)%D + a1%D ですが、ここで (m0*2^b)/D と (m0*2^b)%D をb[bit]の非負整数に対する演算のみ(ループ処理も含めたくない)を用いて計算する方法が思いつかないのですが、何か良い方法はありませんでしょうか? 上記が計算できれば、 商 d = d0*2^b + d1. 余り m = m1 と構成できます。

質問者が選んだベストアンサー

  • ベストアンサー
  • mtaka2
  • ベストアンサー率73% (867/1179)
回答No.1

まず、質問者さんの立てた式には、計算過程に誤りがあります。 d1 = (m0*2^b)/D + a1/D m1 = (m0*2^b)%D + a1%D この「/」が整数除算だとすると、この/・%では、正しい計算はできません。 (例えば、b=4bitで考えましょう。50=4*2^4+2ですが、これを7で割った場合、 (4*2^4)/7+2/7=48/7+2/7=6+0=6 (4*2^4)%7+2%7=48%7+2%7=6+2=8 つまり、50を7で割った商が6で余り8になってしまいます。 つまり、個別に出した商や余りを単純に足すことはできません。 さて、まず a0をDで割った商をa0d、余りをa0m a1をDで割った商をa1d、余りをa1m 2^bをDで割った商をbd、余りをbm (a0*2^b+a1)をDで割った商を(d0*2^d+d1)、余りをm とします。 このとき、元の数 a0、a1、2^bは、 a0 = a0d * D + a0m a1 = a1d * D + a1m 2^b= bd * D + bm という式が成り立ちますから、被除数 a0*2^b+a1 は、 (a0*2^b+a1) = (a0d * D + a0m)*2^b+(a1d * D + a1m) = (a0d*2^b+a1d)*D + (a0m*2^b+a1m) になります。ここで、右側の2^bに2^b= bd * D + bmを代入すると、 = (a0d*2^b+a1d)*D + (a0m*(bd*D+bm)+a1m) = (a0d*2^b+a1d+a0m*bd)*D + (a0m*bm+a1m) になります。 余りについては、 (a0d*2^b+a1d+a0m*bd)*D はDで割って余り0ですから、 m=(a0*2^b+a1)%D = (a0m*bm+a1m) % D として求めることができます。 商については、 (a0*2^b+a1)/D = ((a0d*2^b+a1d+a0m*bd)*D + (a0m*bm+a1m))/D = (a0d*2^b+a1d+a0m*bd)*D/D + (a0m*bm+a1m)/D = (a0d*2^b+a1d+a0m*bd) + (a0m*bm+a1m)/D になります。 つまり、基本としては、 d0=a0d d1=a1d+a0m*bd+(a0m*bm+a1m)/D a=(a0m*bm+a1m)%D になります。 (ただし、この計算において、d1がb[bit]からオーバーフローする場合もありえます。 その場合をきちんと検査して、d1から適切な値を引いて適宜d0の方を足す、などとといった処理が必要です また、a0m*bmがb[bit]からオーバーフローする場合もありえますので、そちらの検査も必要。 なお、 > 2^bをDで割った商をbd、余りをbm については、そのままではb[bit]の演算では表現できませんが、 2^(b-1)をDで割った商をbd'、余りをbm' とすると、 2^b=2^(b-1)*2 = (bd'*D+bm')*2 = 2*bd'*D+2*bm' になりますから、 bd=2*bd'+(2*bm')/D bm=(2*bm')%D として、b[bit]の演算で求められます。

mi65536
質問者

お礼

理解できました。丁寧に回答していただき、ありがとうございます。

関連するQ&A

  • C言語signed long long型の演算

    C言語で以下の演算を行った場合、変数bに格納される値が-1(0xFFFFFFFFFFFFFFFF)になることを期待しておりましたが、参照すると4294967295(0x00000000FFFFFFFF)となってしまいます。 unsigned int a = 1; signed long long b; b = a * (-1); 32bit、64bitのUNIX(Solaris)マシンでそれぞれ確認しましたが、どちらも同じ結果となりました。 変数aの型宣言をsigned intにすると変数bが-1(0xFFFFFFFFFFFFFFFF)になることは確認したのですが、unsigned intだとなぜこのような演算結果となるのかが分かりません。 ※8バイト整数に格納する際に先頭4バイトがなぜ0xFFFFFFFFで補完されないのか? ちなみに変数bの型宣言をsigned long intにすると32bitマシンでは-1となりましたが、64bitマシンでは4294967295となってしまいます。 これは32bitUNIXマシンではsigned long intは4バイト領域であるため-1(0xFFFFFFFF)となり、64bitUNIXマシンでは8バイト領域のため前述と同じ結果になるのだと考えますが、なぜ8バイト整数を使用するとこのような演算が行われるのかが分からないので、演算順序や型変換の優先順位がどのように行われいるのか説明できる方教えてください。

  • Javascriptで算術演算子を作っているのですがわかりません・・・

    あの、JavaScriptの課題で、算術演算子つくり、加算、減算、乗算、除算、整数の除算の商と余りが求めれるように、a bにそれぞれ数値を代入して計算開始というのを作りました。それで、数値以外のたとえば、アルファベットなどを代入した場合、それは数値ではありません、数値を代入してくださいというような数値の入力を促すようになるようにしたいのですが、エラーばかりでます。どのようにソースを打ったら良いのかさっぱりわかりません。教えてください!!よろしくおねがいします。

  • 商と剰余を同時に求める(C言語)

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

  • C言語の課題で困っています。その1.四則演算

    二つの整数値を読み込んで、前者を後者で割り、その結果の商と余りを表示するプログラムを作成。 実行例にあるよう、ゼロで割るような場合への対処も考慮する。 実行例1: 整数の除算を行います。整数を入力してください。 整数A:13 整数B:5 13 ÷ 5 = 2 あまり 3 実行例2: 整数の除算を行います。整数を入力してください。 整数A:10 整数B:0 0でわることはできません! (注)プログラム実行時にキーボードからどんな整数を入力してもいいように作成すること。 という課題に取り組んでいますが、途中までしか記述できません。 どなたか助けてください。 下記が途中までの記述です。 /*二つの整数値を読み込んで、前者を後者で割り、その結果の商と余りを表示*/ #include <stdio.h> int main(void) { int na, nb; printf("shimasaki kazunori \n"); puts("整数の除算を行います。整数を入力してください。: \n"); printf("整数A:"); scanf("%d", &na); printf("整数B:"); scanf("%d", &nb); printf("na ÷ nb = %d あまり %d \n", na / nb, nb, na % nb); return(0); }

  • a,b,cはa^2-3b^2=c^2を満たす整数とするとき、次のことを

    a,b,cはa^2-3b^2=c^2を満たす整数とするとき、次のことを証明せよ。 1、a,bの少なくとも一方は偶数である。 2、a,bが共に偶数なら、少なくとも一方は4の倍数である。 3、aが奇数ならbは4の倍数である。 という問題です。 1はa,bを奇数として、2m+1,2n+1とおいて計算したのですが、いまいちどう証明したらよいのか分かりません。 2はどちらも2m,2nとして計算したら、4(m^2-3n^2)=c^2となったのですが、これで何の証明になるのか…。 3もよく分かりません。 勉強不足で申し訳ありません。考え方だけでも教えてください。よろしくお願いします。

  • 四則演算についてです

    四則演算の除算法についてですが {23/6}を2進数で求めたいです。 但し、被除数は6ビット、除数は4ビットという条件付き。 23=(0 10111)2 6=(0 110)2 2の補数を用いて-6=(1 010)2 減算結果が正の場合、商として1をたて 減算結果が負の場合、商として0を立てるのですが 010111 +)1010    商 --------- 111111 …0 +) 1010 --------- 1010011 …0 +) 1010 --------- 1101 …0 +) 1010 --------- 10111 となってしまい商と余りがうまく出ません! 間違ってるところ教えてください!

  • 勉強の参考にさせて下さい

    前回と同じようにもう一つ過去問を手に入れたのですが、同じく回答が手に入らず困っています。 大変お手数だとは思いますが、もうすぐ行われる期末テストの参考にしたいので、出来る範囲で構いませんのでもしどなたか解いて頂ければ大変うれしく思います。 どうかよろしくお願いいたします。 引き放し法除算において各ステップで次のような処理を行うことで,整数の除算を実行でき る.但し,ri はi ステップ目の中間余り, qi は商のi ビット,D は除数である. ・中間余りを左シフトして2ri-1 を求める. ・if(2ri-1 * D >= 0) qi = 1; else qi = -1; ・ri = 2ri-1 - qi D (1) 被除数(X):00100110 (38),除数(D):0110 (6)のときのこの方式による除算ステップを 示せ. (2) 被除数(X):11011010 (-38),除数(D):1010(-6)のときのこの方式による除算ステップを 示せ. [3]IEEE754 標準浮動小数点数に関して以下の問に答えよ. (1)0xafbf0000 という表現のfloat 数の10 進の値(m X 2e の形式でよい)を求めよ. (2)-938.8125 のfloat 表現(16 進数)を求めよ. (3) int では表現できないが,float なら表現できる整数のうち,次の数を求めよ. (a) 正で絶対値が最小(最も0 に近い) (b) 負で絶対値が最小(最も0 に近い) [4]キャスト操作やfloat/double データ型を使用せずに,入力された数のビットを処理して, int/unsigned 数をIEEE754 表現のfloat にキャストする関数とそのドライバをC 又はC++ を用いて次のように書け. (1)処理関数:次のいずれかを選択して書け. (a) unsigned iToF(int): int 数をfloat に変換し,unsigned 数として返す.ま るめはIEEE default の“nearest, half way case to even”. (b) unsigned uToF(unsigned): unsigned 数をfloat に変換し,unsigned 数と して返す.まるめは切り捨て. (2)main 関数: 整数(無符号整数)を入力するとiToF(uToF)を用いて浮動小数点数 に変換してそのビットパターンを16 進で出力せよ.次に,そのfloat としての値を再度出 力し,入力した値と比較してみよ.それらは必ず一致するか.

  • 非負整数nを読み込んで、1+2+・・・+m>nとなる最小の整数mを表示

    非負整数nを読み込んで、1+2+・・・+m>nとなる最小の整数mを表示するというプログラミングなのですが・・・ #include <stdio.h> int main(void) { int n,m=■ , sum=0; do { printf("非負整数: "); scanf("%d", &n); } while (n■0); while (sum■n) { ■ ; sum +=■; } printf("1+2+・・・+m> %dとなる最小の整数mは%dである。\n", n, m); return (0); } ■のところがわかる方どうにかお願いします!!

  • 算術演算子にて、整数での除算処理は商になる?

    JAVAのプログラミングを勉強しているのですが、JAVAの算術演算子にて、 参考書に「除算演算子は割り算を行うものだが、整数同士の割り算を用いると「商」を計算する」と書かれているのですが、これはどういう意味でしょうか? 整数同士の割り算をすると、小数点ではなく四捨五入をした整数値が出力されるのでしょうか?

    • ベストアンサー
    • Java
  • べき乗の定義は負の整数へと拡張できるのか(再)

    べき乗の定義は (1) a^1 = a (2) a^(p+1) = a^p * a ただし p は正の整数 となります。 この定義が、このまま負の整数へと拡張できるかどうかを考えてみました。 p=0 へと拡張するならば、 (A) a = a^0 * a という式が加わります。 a≠0 であれば a^0=1 となり a=0 なら 0^0 はどんな値も許され、0^0 は「不定」と言われます。 いずれにせよ、(1)(2)が成立するように a^0 の値を選ぶことができます。 p=-1 へと拡張するならば、さらに (B) a^0 = a^-1 * a という式が加わります。 a≠0 であれば a^-1=1/a となり a=0 なら 0^0=0 とした上で 0^-1 はどんな値も許されます。 さらに続けていくと、 (3) a^0 = 1 ただし a≠0 (4) a^(-p) = 1/(a^p) ただし a≠0, p は整数 (5) 0^(-p) = 0 ただし p は整数 という式が成立するように値を選ぶなら、べき乗の定義を負の整数へと拡張できることが分かります。 ところが、0^0 は 「不定」として扱うのが普通です。 これは、負の整数への拡張を考えていないから、と理解すればいいのでしょうか? そして、負の整数への拡張を前提とするなら、0^0=0 として扱うべきでしょうか?

専門家に質問してみよう