Comment créer des entiers 0..9 et des opérateurs mathématiques + - * / dans des chaînes binaires. Par exemple:
0 = 0000,
1 = 0001,
...
9 = 1001
Existe-t-il un moyen de faire cela avec Ruby 1.8.6 sans utiliser de bibliothèque?
Comment créer des entiers 0..9 et des opérateurs mathématiques + - * / dans des chaînes binaires. Par exemple:
0 = 0000,
1 = 0001,
...
9 = 1001
Existe-t-il un moyen de faire cela avec Ruby 1.8.6 sans utiliser de bibliothèque?
Réponses:
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
("%08b" % int)
ou ("%08b" % string)
pour renvoyer un nombre fixe de bits.
-9.to_s(2)
=> "-1001"
Quelqu'un peut-il expliquer cela?
9
est 1001
en binaire.
J'ai posé une question similaire . Sur la base de la réponse de @sawa , la manière la plus succincte 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 de largeur fixe:
1.upto(10).each { |n| puts "%04b" % n }
0001
0010
0011
0100
0101
0110
0111
1000
1001
1010
245.to_s(2)
seront plus rapides que"%b" % 245
Reprenant l'idée de table de recherche de bta, vous pouvez créer la table de recherche 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"}
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 que 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
Si vous travaillez uniquement avec les chiffres uniques 0-9, il est probablement plus rapide de créer une table de recherche afin que vous n'ayez pas à 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 donnera sa représentation binaire sous forme de chaîne.
Si vous souhaitez que les chaînes binaires comportent un certain nombre de chiffres (conservez les zéros non significatifs), passez x.to_s(2)
à sprintf "%04b", x
(où 4
est le nombre minimum de chiffres à utiliser).
Si vous recherchez une classe / méthode Ruby, j'ai utilisé ceci, 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