如何在Ruby中将字符串或整数转换为二进制?


168

如何创建整数0..9和数学运算符+-* /转换为二进制字符串。例如:

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

有没有办法在不使用库的情况下使用Ruby 1.8.6做到这一点?


当您说要将数学运算符转换为二进制字符串时,这到底是什么意思?使用以二进制形式编写的ASCII表示形式?
bta 2010年

我猜你想做流行的遗传算法吗?:-)
nemesisfixx 2012年

Answers:


372

您拥有Integer#to_s(base)String#to_i(base)可以使用。

Integer#to_s(base) 将十进制数字转换为表示指定基数的字符串:

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

相反,则可通过String#to_i(base)以下方式获得:

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

24
@TomRavenscroft此外,您可以使用("%08b" % int)("%08b" % string)返回固定数量的位。
衰减

1
辉煌的迈克,灿烂的露比!
塔默·斯拉什

4
-9.to_s(2) => "-1001"有人可以解释吗?
user1201917

1
对于像我这样@decay
Taylor Liss

@ user1201917怎么了?91001二进制的。
preferred_anon19年

41

我问了类似的问题。根据@sawa的答案,以二进制格式表示字符串中整数的最简洁的方法是使用字符串格式化程序:

"%b" % 245
=> "11110101"

您还可以选择字符串表示形式的长度,如果要比较固定宽度的二进制数,这可能会很有用:

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

如果仅使用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", x(其中使用4的最小数字位数)。


@ bta-我将所有这些字符编码为二进制,因此可以在遗传算法中使用它们。我真的很喜欢为编码/解码查找表的想法,因为该集限制为0..9和+-* /
mcmaloney 2010年

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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.