- ベストアンサー
2進数データのビット演算
vb.netにて 0と1からなる2進数で記録した2つの値をビット演算したいと思っております。 Convert.ToInt32("1111101000", 2) などを使って、一度数値に変換して演算すれば、計算可能なことはわかったのですが、計算に利用したいデータが2進数で1000桁ほどあります。桁数が多い場合、Convert.ToInt32ではエラーが出て実行できません。 無数に長い2進数のデータをビット演算するにはどうすればよろしいでしょうか。 ご存知の方、ご教授よろしくお願いいたします。
- みんなの回答 (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)
その他の回答 (3)
- dsuekichi
- ベストアンサー率64% (171/265)
> ループでまわすよりも、何か高速に処理できる方法がありましたら さて? ちゃんと計測したことはありませんが・・・ 高々1000回(1000桁)のループですよね? 十分高速(と言うか、たいした時間は掛からない)と思いますが・・・ 下手なことをすると、「文字列」=>『高速と思われる処理で扱えるデータ型』=>「文字列」 と言う、データ型の変換部分のオーバーヘッドが馬鹿にならなくなる可能性も・・・ #「Simple Is Best!!」 どの程度、「高速化」が必要(または「高速化できたらいいな」)と考えていらっしゃるのでしょうか?
補足
ご回答ありがとうございます。 おっしゃるとおり、実験してみましたが、高速に処理できました。 実際には、1000桁の2進数データ(文字列またはバイト配列、boolean配列など、形式はまだ決めていません)を20個ほどの組み合わせる演算を100セット行う予定です。つまり、200万回ループをまわす程度の計算を考えています。 boolean配列で、200万回のループ計算実験でも1秒かかりませんでした。 実は、質問前に、アプリを組んだときに、実装方法がとんでもなく悪く180秒ほどかかっていたため、処理に時間がかかると思い込んでいました。実際には、メインの処理ではなく、データを格納したhashtableからデータを取得するルーチンが遅く、そのルーチンを200万回呼び出していたのが遅い原因でした。
- dsuekichi
- ベストアンサー率64% (171/265)
> 0と1からなる2進数で記録した2つの値をビット演算したいと思っております。 > Convert.ToInt32("1111101000", 2) などを使って、 > 進数で1000桁ほどあります 「ビット演算」と言いながら、実体は文字列("0"と"1")なんでしょうか? でしたら、単純にループで1文字ずつ取り出して、変換するとかはどうでしょう? ANDなら「両方"1"なら"1"、その他は"0"」 ORなら「両方"0"なら"0"、その他は"1"」 等単純な条件文で済みますよね?
補足
回答ありがとうございます。 そうなんです。 私も良く考えたら、ループで回せばいいと気がつきました。 ただ、ループでまわすよりも、何か高速に処理できる方法がありましたら、教えていただければ幸いです。
- Schwarz20
- ベストアンサー率46% (6/13)
Integer型や、Long型などの整数型として、計算するのは無理かと思います。数値としては、Double型で表現は出来ると思いますが、精度は無くなります ANDやOR等のビット演算だけであれば、32桁(32bit)ごとに区切って、計算させるのが良いかと思います 32桁ごとに区切るには、Mid関数を使って32桁ごとに取り出すと良いかと思います
お礼
ソースコードまで用意していただきありがとうございました。 ソースコードを元に、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倍ほど処理速度に差が出ました。 皆様どうもありがとうございました。