¿Cómo se crean enteros 0..9 y operadores matemáticos + - * / en cadenas binarias? Por ejemplo:
0 = 0000,
1 = 0001,
...
9 = 1001
¿Hay alguna manera de hacer esto con Ruby 1.8.6 sin usar una biblioteca?
¿Cómo se crean enteros 0..9 y operadores matemáticos + - * / en cadenas binarias? Por ejemplo:
0 = 0000,
1 = 0001,
...
9 = 1001
¿Hay alguna manera de hacer esto con Ruby 1.8.6 sin usar una biblioteca?
Respuestas:
Tienes Integer#to_s(base)
y String#to_i(base)
disponible para ti.
Integer#to_s(base)
convierte un número decimal en una cadena que representa el número en la base especificada:
9.to_s(2) #=> "1001"
mientras que el reverso se obtiene con String#to_i(base)
:
"1001".to_i(2) #=> 9
("%08b" % int)
o ("%08b" % string)
para devolver un número fijo de bits.
-9.to_s(2)
=> "-1001"
¿Alguien puede explicar esto?
9
Está 1001
en binario.
Hice una pregunta similar . Según la respuesta de @sawa , la forma más sucinta de representar un número entero en una cadena en formato binario es usar el formateador de cadena:
"%b" % 245
=> "11110101"
También puede elegir qué tan larga será la representación de cadena, lo que podría ser útil si desea comparar números binarios de ancho fijo:
1.upto(10).each { |n| puts "%04b" % n }
0001
0010
0011
0100
0101
0110
0111
1000
1001
1010
245.to_s(2)
serán más rápidos que"%b" % 245
Al retomar la idea de la tabla de búsqueda de bta, puede crear la tabla de búsqueda con un bloque. Los valores se generan cuando se accede por primera vez y se almacenan para más adelante:
>> 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"}
Naturalmente Integer#to_s(2)
, lo usaría , String#to_i(2)
o "%b"
en un programa real, pero, si está interesado en cómo funciona la traducción, este método calcula la representación binaria de un entero dado utilizando operadores básicos:
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
Para comprobar que funciona:
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 solo está trabajando con los dígitos individuales 0-9, es probable que sea más rápido crear una tabla de búsqueda para que no tenga que llamar a las funciones de conversión cada vez.
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"
La indexación en esta tabla hash usando el número entero o la representación de cadena de un número producirá su representación binaria como una cadena.
Si necesita que las cadenas binarias tengan un cierto número de dígitos (mantenga los ceros a la izquierda), cambie x.to_s(2)
a sprintf "%04b", x
(donde 4
es el número mínimo de dígitos a usar).
Si está buscando una clase / método Ruby, lo usé y también he incluido las pruebas:
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