web-dev-qa-db-fra.com

Comment convertir une chaîne ou un entier en binaire en Ruby?

Comment créer des entiers 0..9 et des opérateurs mathématiques + - */in en chaînes binaires. Par exemple:

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

Est-il possible de faire cela avec Ruby 1.8.6 sans utiliser de bibliothèque?

160
mcmaloney

Vous avez Integer#to_s(base) et String#to_i(base) à votre disposition.

Integer#to_s(base) convertit un nombre décimal en une chaîne représentant le nombre dans la base spécifiée:

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

tandis que l'inverse est obtenu avec String#to_i(base):

"1001".to_i(2) #=> 9
353
Mike Woodhouse

J'ai demandé ne question similaire . Basé sur la réponse de @ sawa , le moyen le plus succinct de représenter un entier dans une chaîne au format binaire est d'utiliser le formateur de chaîne:

"%b" % 245
=> "11110101"

Vous pouvez également choisir la longueur de la représentation sous forme de chaîne, ce qui peut être utile si vous souhaitez comparer des nombres binaires à largeur fixe:

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

Reprenant l'idée de la table de consultation de bta, vous pouvez créer la table de consultation avec un bloc. Les valeurs sont générées lors de leur premier accès et stockées pour plus tard:

>> 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"}
20
Michael Kohl

Vous utiliseriez naturellement Integer#to_s(2), String#to_i(2) ou "%b" dans un programme réel, mais si vous êtes intéressé par le fonctionnement de la traduction, cette méthode calcule la représentation binaire d'un entier donné à l'aide d'opérateurs de base:

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

Pour vérifier cela fonctionne:

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

Si vous travaillez uniquement avec les chiffres simples compris entre 0 et 9, il est probablement plus rapide de créer une table de recherche afin de ne pas avoir à appeler les fonctions de conversion à chaque fois.

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"

L'indexation dans cette table de hachage à l'aide de la représentation entière ou sous forme de chaîne d'un nombre produira sa représentation binaire sous forme de chaîne.

Si vous souhaitez que les chaînes binaires comportent un certain nombre de chiffres (laissez des zéros), remplacez x.to_s(2) par sprintf "%04b", x (Où 4 Est le nombre minimal de chiffres utiliser).

4
bta

Si vous recherchez une classe/méthode Ruby), je l’ai utilisée et j’ai également inclus les tests:

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