Ruby'de bir dize veya tamsayıyı ikiliye nasıl dönüştürebilirim?


168

İkili dizelere 0..9 tamsayıları ve matematik operatörleri + - * / in nasıl oluşturulur. Örneğin:

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

Bunu kütüphane kullanmadan Ruby 1.8.6 ile yapmanın bir yolu var mı?


Matematik operatörlerini ikili dizelere dönüştürmek istediğinizi söylediğinizde tam olarak ne demek istiyorsunuz? İkili olarak yazılmış ASCII gösterimini kullanın?
— bta

Ben popüler Genetik Algoritma şey yapmak istedim sanırım? :-)
— nemesisfixx

Yanıtlar:


372

Sen var Integer#to_s(base)ve String#to_i(base)sizin için kullanılabilir.

Integer#to_s(base) ondalık bir sayıyı, belirtilen tabandaki sayıyı temsil eden bir dizeye dönüştürür:

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

tersi ile elde edilirken String#to_i(base):

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

24
@TomRavenscroft Ayrıca, sabit sayıda bit döndürmek için ("%08b" % int)veya ("%08b" % string)düğmesini kullanabilirsiniz .
— çürüme

1
Harika Mike, Parlak Yakut!
— Tamer Shlash

4
-9.to_s(2) => "-1001"Birisi bunu açıklayabilir mi?
— user1201917 15:17


@ user1201917 Bunun nesi var? 9olduğu 1001ikilik sistemde.
— preferred_anon

41

Benzer bir soru sordum . @Sawa'nın cevabına dayanarak, bir dizede bir tamsayıyı ikili biçimde göstermenin en kısa yolu dize biçimlendiricisini kullanmaktır:

"%b" % 245
=> "11110101"

Ayrıca, sabit genişlikli ikili sayıları karşılaştırmak istiyorsanız yararlı olabilecek dize temsilinin ne kadar uzun olacağını da seçebilirsiniz:

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

6
Tam sayıları ikili dizeye dönüştürmek için bazı yerel testler yaptım, ancak sonuç, gibi kodların 245.to_s(2)daha hızlı olacağını gösteriyor"%b" % 245
— Green Su

Ayrıca bu negatif değerlerle düzgün çalışmaz.
— alex

21

Bta'nın arama tablosu fikrini alarak, bir blok ile arama tablosu oluşturabilirsiniz. Değerler, daha sonra ilk kez erişilip saklandığında üretilir:

>> 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

Sen doğal olarak kullanırsınız Integer#to_s(2), String#to_i(2)ya "%b"sen nasıl tercüme eserler ilgilenen eğer, gerçek bir programda, ancak bu yöntem, temel operatörleri kullanarak tamsayı verilen ikili gösterimini hesaplar:

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

Çalışıp çalışmadığını kontrol etmek için:

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

Yalnızca 0-9 arasındaki tek rakamlarla çalışıyorsanız, bir arama tablosu oluşturmak daha hızlıdır, böylece her seferinde dönüşüm işlevlerini çağırmanız gerekmez.

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"

Bu karma tabloya bir sayının tamsayı veya dize gösterimi kullanılarak endekslenmesi, dize olarak ikili temsilini verir.

Eğer (lider sıfırları tutun) uzun belirli bir basamak sayısını olmaya ikili dizeleri gerektiriyorsa, o zaman değiştirmek x.to_s(2)için sprintf "%04b", x(burada 4kullanımına basamak asgari sayı).


@ bta- Genetik algoritmada kullanabilmem için tüm bu karakterleri ikiliye kodluyorum. Gerçekten kodlamak / kod çözme için bir arama tablosu fikir gibi kümesi 0..9 sınırlı ve olduğundan + - * /
— mcmaloney

2

Ruby sınıf / yöntem arıyorsanız ben bunu kullandım ve ben de testleri dahil:

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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.