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.