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?
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
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
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"}
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
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).
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