Rubyで文字列または整数をバイナリに変換する方法は?


168

バイナリ文字列に整数0..9と数学演算子+-* /を作成するにはどうすればよいですか。例えば:

 0 = 0000,
 1 = 0001, 
 ...
 9 = 1001

ライブラリを使用せずにRuby 1.8.6でこれを行う方法はありますか?


数学演算子をバイナリ文字列に変換する場合、正確にはどういう意味ですか?バイナリで書かれたASCII表現を使用しますか?
bta

私はあなたが人気のある遺伝的アルゴリズムのことをしたかったと思いますか?:-)
nemesisfixx 2012年

回答:


372

あなたが持っておりInteger#to_s(base)、あなたがString#to_i(base)利用できます。

Integer#to_s(base) 10進数を指定された基数の数値を表す文字列に変換します。

9.to_s(2) #=> "1001"

逆は次のようにして得られString#to_i(base)ます:

"1001".to_i(2) #=> 9

24
@TomRavenscroftさらに、("%08b" % int)または("%08b" % string)を使用して、固定数のビットを返すことができます。
2013

1
ブリリアントマイク、ブリリアントルビー!
Tamer Shlash、2014年

4
-9.to_s(2) => "-1001"誰かがこれを説明できますか?
user1201917 2017年

1
私のような@decay
Taylor Liss

@ user1201917どうしたの?9ある1001バイナリで。
preferred_anon

41

私は尋ねた同様の質問を@sawaの回答に基づいて、文字列内の整数をバイナリ形式で表す最も簡単な方法は、文字列フォーマッタを使用することです。

"%b" % 245
=> "11110101"

文字列表現の長さを選択することもできます。これは、固定幅の2進数を比較する場合に便利です。

1.upto(10).each { |n| puts "%04b" % n }
0001
0010
0011
0100
0101
0110
0111
1000
1001
1010

6
整数をバイナリ文字列に変換するためにいくつかのローカルテストを実行しましたが、結果は次のようなコード245.to_s(2)が高速になることを示しています"%b" % 245
Green Su

また、これは負の値では適切に機能しません。
アレックス

21

btaのルックアップテーブルのアイデアを取り上げ、ブロックを使用してルックアップテーブルを作成できます。値は、最初にアクセスされたときに生成され、後で保存されます。

>> lookup_table = Hash.new { |h, i| h[i] = i.to_s(2) }
=> {}
>> lookup_table[1]
=> "1"
>> lookup_table[2]
=> "10"
>> lookup_table[20]
=> "10100"
>> lookup_table[200]
=> "11001000"
>> lookup_table
=> {1=>"1", 200=>"11001000", 2=>"10", 20=>"10100"}

11

自然にInteger#to_s(2)String#to_i(2)または"%b"実際のプログラムで使用しますが、変換の動作に興味がある場合、このメソッドは基本的な演算子を使用して、指定された整数のバイナリ表現を計算します。

def int_to_binary(x)
  p = 0
  two_p = 0
  output = ""

  while two_p * 2 <= x do
    two_p = 2 ** p
    output << ((two_p & x == two_p) ? "1" : "0")
    p += 1
  end

  #Reverse output to match the endianness of %b
  output.reverse
end

それが動作することを確認するには:

1.upto(1000) do |n|
  built_in, custom = ("%b" % n), int_to_binary(n)
  if built_in != custom
    puts "I expected #{built_in} but got #{custom}!"
    exit 1
  end
  puts custom
end

4

1桁の0から9だけで作業している場合は、ルックアップテーブルを作成する方が速いため、毎回変換関数を呼び出す必要はありません。

lookup_table = Hash.new
(0..9).each {|x|
    lookup_table[x] = x.to_s(2)
    lookup_table[x.to_s] = x.to_s(2)
}
lookup_table[5]
=> "101"
lookup_table["8"]
=> "1000"

数値の整数表現または文字列表現を使用してこのハッシュテーブルにインデックスを付けると、そのバイナリ表現が文字列として生成されます。

バイナリ文字列を特定の桁数(先頭のゼロを維持)にする必要がある場合は、に変更x.to_s(2)しますsprintf "%04b", x4は使用する最小桁数です)。


@ bta-これらの文字をすべてバイナリにエンコードして、遺伝的アルゴリズムで使用できるようにします。私は実際にエンコード/デコードのためのルックアップテーブルのアイデアのようにセットが0..9に限定されているので+ - * /
mcmaloney

2

Rubyのクラス/メソッドを探している場合は、これを使用し、テストも含めました。

class Binary
  def self.binary_to_decimal(binary)
    binary_array = binary.to_s.chars.map(&:to_i)
    total = 0

    binary_array.each_with_index do |n, i|
      total += 2 ** (binary_array.length-i-1) * n
    end
    total
   end
end

class BinaryTest < Test::Unit::TestCase
  def test_1
   test1 = Binary.binary_to_decimal(0001)
   assert_equal 1, test1
  end

 def test_8
    test8 = Binary.binary_to_decimal(1000)
    assert_equal 8, test8
 end

 def test_15
    test15 = Binary.binary_to_decimal(1111)
    assert_equal 15, test15
 end

 def test_12341
    test12341 = Binary.binary_to_decimal(11000000110101)
    assert_equal 12341, test12341
 end
end
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.