• ベストアンサー

2進数データのビット演算

vb.netにて 0と1からなる2進数で記録した2つの値をビット演算したいと思っております。 Convert.ToInt32("1111101000", 2) などを使って、一度数値に変換して演算すれば、計算可能なことはわかったのですが、計算に利用したいデータが2進数で1000桁ほどあります。桁数が多い場合、Convert.ToInt32ではエラーが出て実行できません。 無数に長い2進数のデータをビット演算するにはどうすればよろしいでしょうか。 ご存知の方、ご教授よろしくお願いいたします。

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

  • ベストアンサー
  • Schwarz20
  • ベストアンサー率46% (6/13)
回答No.4

ANo1です ソースコードを書いてみました これを参照してください 32桁分を取り出すのに、Mid関数でなく、SubStringメソッドを使用しています 以下、ソースコード Dim strBitValue1 As String Dim strBitValue2 As String Dim strBitValueRes As String ' 計算を行うビットの文字列 strBitValue1 = "10000000111111111000001111111110001" strBitValue2 = "10000000111111111000001000000110000" Dim intVal1 As Integer Dim intVal2 As Integer Dim intValRes As Integer Dim intLeng As Integer Dim Idx As Integer For Idx = 0 To strBitValue1.Length Step 32   ' 取り出す桁数を決める   intLeng = 32   If ((strBitValue1.Length - Idx) < 32) Then     intLeng = strBitValue1.Length - Idx   End If   ' 取り出した桁数を整数値に変換する   intVal1 = Convert.ToInt32(strBitValue1.Substring(Idx, intLeng), 2)   intVal2 = Convert.ToInt32(strBitValue2.Substring(Idx, intLeng), 2)   ' ビット演算を行う   intValRes = intVal1 And intVal2   ' 計算結果を文字列にして連結する   strBitValueRes = strBitValueRes & Convert.ToString(intValRes, 2).PadLeft(intLeng, "0") Next ' 計算結果を表示する Debug.WriteLine(strBitValueRes)

from2001
質問者

お礼

ソースコードまで用意していただきありがとうございました。 ソースコードを元に、1000桁の2進数を2つ用意して、その2つのビット演算を2000回、つまり、合計200万桁のビット演算を行うテストをしましたが1秒かからずに実行完了しました。 ありがとうございました。 結論的には、200万桁程度であれば、ループで1桁ずつまわしても、32桁ずつIntegerに変換してビット演算しても高速に処理できることがわかりました。 ちなみに、 32桁ごとのビット演算200万桁(1000桁の32桁区切りを2000セット):600ミリ秒。 配列数1000のboolean配列の演算2000セット:46ミリ秒。 でした。 参考まで:ループで回すときに用いる変数の型の方が結果に影響を与えていることがわかりました。 http://www.kabugraph.jp/blog/from2001/d/426 こちらは、データ型の種類により300倍から700倍ほど処理速度に差が出ました。 皆様どうもありがとうございました。

その他の回答 (3)

  • dsuekichi
  • ベストアンサー率64% (171/265)
回答No.3

> ループでまわすよりも、何か高速に処理できる方法がありましたら さて? ちゃんと計測したことはありませんが・・・ 高々1000回(1000桁)のループですよね? 十分高速(と言うか、たいした時間は掛からない)と思いますが・・・ 下手なことをすると、「文字列」=>『高速と思われる処理で扱えるデータ型』=>「文字列」 と言う、データ型の変換部分のオーバーヘッドが馬鹿にならなくなる可能性も・・・ #「Simple Is Best!!」 どの程度、「高速化」が必要(または「高速化できたらいいな」)と考えていらっしゃるのでしょうか?

from2001
質問者

補足

ご回答ありがとうございます。 おっしゃるとおり、実験してみましたが、高速に処理できました。 実際には、1000桁の2進数データ(文字列またはバイト配列、boolean配列など、形式はまだ決めていません)を20個ほどの組み合わせる演算を100セット行う予定です。つまり、200万回ループをまわす程度の計算を考えています。 boolean配列で、200万回のループ計算実験でも1秒かかりませんでした。 実は、質問前に、アプリを組んだときに、実装方法がとんでもなく悪く180秒ほどかかっていたため、処理に時間がかかると思い込んでいました。実際には、メインの処理ではなく、データを格納したhashtableからデータを取得するルーチンが遅く、そのルーチンを200万回呼び出していたのが遅い原因でした。

  • dsuekichi
  • ベストアンサー率64% (171/265)
回答No.2

> 0と1からなる2進数で記録した2つの値をビット演算したいと思っております。 > Convert.ToInt32("1111101000", 2) などを使って、 > 進数で1000桁ほどあります 「ビット演算」と言いながら、実体は文字列("0"と"1")なんでしょうか? でしたら、単純にループで1文字ずつ取り出して、変換するとかはどうでしょう? ANDなら「両方"1"なら"1"、その他は"0"」 ORなら「両方"0"なら"0"、その他は"1"」 等単純な条件文で済みますよね?

from2001
質問者

補足

回答ありがとうございます。 そうなんです。 私も良く考えたら、ループで回せばいいと気がつきました。 ただ、ループでまわすよりも、何か高速に処理できる方法がありましたら、教えていただければ幸いです。

  • Schwarz20
  • ベストアンサー率46% (6/13)
回答No.1

Integer型や、Long型などの整数型として、計算するのは無理かと思います。数値としては、Double型で表現は出来ると思いますが、精度は無くなります ANDやOR等のビット演算だけであれば、32桁(32bit)ごとに区切って、計算させるのが良いかと思います 32桁ごとに区切るには、Mid関数を使って32桁ごとに取り出すと良いかと思います

関連するQ&A

  • ビット演算子について

    あるプログラムの中で下記のようなif文の記述を見かけました。 どういう計算をしてif文の判定を行っているのでしょうか。 (1)256を2進数に変換して → 100000000 (2)0x00000004を2進数に変換して → 100 (3)100000000 & 100 のビットAND演算を行う そもそも(3)で100000000 と 100 では桁数が違うけどどうやって両者でビット演算するので しょうか。100を 000000100というように0を補完して計算すればよいのでしょうか。 その場合、100000000 & 000000100 → 000000000(2進数) → 0(10進数) となりif文の中には入らないことになると思います。 if(256 & 0x00000004 != 0)

  • ビット演算で00000001と1の頭に0を付ける?

    https://www.grapecity.com/japan/powernews/column/clang/019/page02.htm ビット演算子 表1にCのビット演算子を掲げておきます。ビット演算とは言っても、扱う値はバイト単位などCの一般的な整数のデータ型です。ビット演算子は、それらの値をビット単位で計算します。 ビットシフト演算(<< >>)~2倍と1/2 例えばunsigned char型の1は、2進数では"00000001"という形のビット列(ビットパターン)になります。これを1桁左にずらす(シフトする)と"00000010"となります。ずらしてあふれた左端の0は消え、空いた右端には0が入ります。 "00000001"は10進数の「1」、"00000010"は10進数の「2」です。つまり、ビット列を左に1桁シフトすると値は2倍になるのです。 -----------------------------------------  以上ですが、C言語の、ビット演算の解説の抜粋です。ビット演算はまだ覚えたてですが、"00000001"整数1の頭にわざわざ、0を沢山 つける目的は何なのでしょうか!?  よろしくお願いします。

  • ビット演算子~について。

    質問があるのですがよろしくお願いします。 環境は Windows Home Editon PHP 5.2.0 Apache 2.2.3 です。 PHPのビット演算子、「~」についてなのですが、 http://wisdom.sakura.ne.jp/programming/php/php8.html このページを見ると、~が式のビットを全て反転させる演算子であると書いてあるのですが、 echo ~5; を実行すると、なぜかブラウザに表示されるのは-6です。 10進数の5を2進数に変換すると0101で、それを~演算子を使って反転させると1010なので、ブラウザに表示される数字は10であるべきではないのでしょうか。返り値が-6という負数になってしまうのも何故だか分かりません。 詳しい方いらっしゃいましたら、ご教授頂けると嬉しいです。 よろしくお願いします。

    • ベストアンサー
    • PHP
  • ビット演算について

    ビット演算について質問なんですが、例えば以下の16ビットのデータ(値は変わる)を 0111 1011 1000 0000 を 0000 0001 1101 1110 や 1111 1111 0000 0000 を 0000 0000 1111 1111 上位にあるビットを下位ビットに、下位にあるビットを上位ビットに に逆に入れたいんですが やり方が分からなく質問しました よろしくお願いします

  • 10進数の実数値の値を32ビットで表す16進法に変換したいのですが

    10進数の実数値の値を32ビットで表す16進法に変換したいのですが 方法がわかりません。 例えば10進(1.23)を16進(70A43F9D)に変換したいのです。 ご存知の方がいらっしゃいましたら宜しくお願いいたします。 環境は、VB2005です。

  • ビット演算について

    いつもお世話になります。 ビット演算について教えて下さい。 unsigned char buf1[1]=0x5a unsigned char buf1[2]=0x04 unsigned char buf1[3]=0x38 5a0438(16)を3バイトの値を12ビットずつの整数で得るにはどうしたらいいのでしょうか? 2進数表記では、 5A | 04 | 38 01011010 | 00000100 | 00111000 12ビットずつとは、 010110100000 010000111000 と区分し、10進数の整数値で得たいです。どのようにすればよいでしょうか? また、0x5Aなどの16進数を2進数のビットで考えるときに、 01011010を下位4ビットを10進数整数を得るにはどうしたらよいのでしょうか? 上記2点、どうぞよろしくお願い致します。

  • ビット演算を使えば出来ますか?

    あるchar型の変数の各ビットを二つずつにして別の変数にしまいたい場合どういうプログラムを作ればいいでしょうか? char型の変数 data1 = 0x51があるとします。 2進数で表すと[01010001] になります。 これを別のchar型の変数に data2=[00110011], data3=[00000011]というふうにしてしまいたいのです。 なにぶん素人なものでうまく説明できませんが各ビットを二つにして横に伸ばすイメージです。 0→00 1→11 となります。 data1=0x33だと[00110011]ですから作りたいデータは data2=[00001111],data3=[00001111]です。 data1=0x12だと[00010010]ですから作りたいデータは data2=[00000011],data3=[00001100]です。 for文とビット演算をつかってdata1からdata2とdata3を作れそうな気はしますがよくわかりません。 説明が分かりにくくて申し訳ありませんが、どなたか教えていただけないでしょうか?

  • チェックボックスをビット演算子で処理したい

    チェックボックスをビット演算子で処理したいのですが、DBに格納した数値をビット演算子で処理する方法がわかりません。 たとえば、北海道から沖縄までのチェックボックスを作成してそれぞれに 1,2,4,8,16,32・・・とvalueを持たせます。 DBには数値の和を入れておきます。 その値を分解してチェックボックスをcheckedにしたいです。 ちょっとわからなくなってしまって。 教えてください、。よろしくお願いします。

    • ベストアンサー
    • PHP
  • ビット反転(Not)が機能しない

    ビット反転(Not)が機能しない VB2005 Framework2を使っています。 現在、テキストボックスに入力した16進数を2進数に変換後ビットを反転させた2進数を再びテキストボックスに表示するプログラムを作っているのですが2進数の反転が上手くいきません。 Convert.ToString関数で2進の変換までは上手くいったのですが、その後代入した変数にNot で反転させて表示させると結果が合わないだけでなく、何故かマイナス表示になったりしてしまいます。 Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Dim X As String = TextBox1.Text Dim Z As String = Convert.ToString(Convert.ToInt32(X, 16), 2) TextBox1.Text = Not Z End Sub Notだけではビットを上手く反転させられないのでしょうか?

  • シフト演算の問題です

     2進数の値を左へn桁移動すると、もとの値の2^n倍になる。 例えば、左へ2ビット桁移動するともとの値の4倍となる。  この性質を利用して、左へ桁移動した値を複数加えることで行う乗算を考える。 なお、ここでは、桁移動して空いたビットには0が入るものとし、負数は考えないものとする。 左へ桁移動する関数として、"SHIFT(値、桁数)"を使う。 この関数は、引数の"値"を"桁数"ビット左へ桁移動した結果を返す。  もとの値をaとし、これを10倍するには、2倍した値と8倍した値を加えればよいので、次のような式になる。  SHIFT(a,1)+SHIFT(a,3) また別の考え方で10倍しようとすると、次のような式になる。  SHIFT((SHIFT(a,x)+a),y) 答えはx=2 y=1 です。 解説をお願いします。

専門家に質問してみよう