Come convertire una stringa o un numero intero in binario in Ruby?


168

Come si creano gli interi 0..9 e gli operatori matematici + - * / in nelle stringhe binarie. Per esempio:

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

C'è un modo per farlo con Ruby 1.8.6 senza usare una libreria?


Quando dici di voler convertire gli operatori matematici in stringhe binarie, cosa intendi esattamente? Utilizzare la rappresentazione ASCII scritta in binario?
dal

Immagino che volessi fare la popolare cosa dell'algoritmo genetico? :-)
nemesisfixx

Risposte:


372

Hai Integer#to_s(base)e String#to_i(base)disponibile per te.

Integer#to_s(base) converte un numero decimale in una stringa che rappresenta il numero nella base specificata:

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

mentre il contrario si ottiene con String#to_i(base):

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

24
@TomRavenscroft Inoltre, è possibile utilizzare ("%08b" % int)o ("%08b" % string)per restituire un numero fisso di bit.
decadimento

1
Brilliant Mike, Brilliant Ruby!
Tamer Shlash,

4
-9.to_s(2) => "-1001"Qualcuno può spiegare questo?
user1201917

1
Per quelli confusi dal codice di @ decay come me, sta usando 'sprintf': apidock.com/ruby/Kernel/sprintf
Taylor Liss

@ user1201917 Cosa c'è che non va? 9è 1001in binario.
favorite_anon,

41

Ho fatto una domanda simile . Basato sulla risposta di @sawa , il modo più breve per rappresentare un numero intero in una stringa in formato binario è usare il formattatore di stringhe:

"%b" % 245
=> "11110101"

Puoi anche scegliere la lunghezza della rappresentazione della stringa, che potrebbe essere utile se desideri confrontare numeri binari a larghezza fissa:

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

6
Ho fatto alcuni test locali per convertire numeri interi in stringa binaria, ma il risultato mostra che codici simili 245.to_s(2)saranno più veloci di"%b" % 245
Green Su

Inoltre, questo non funziona correttamente con valori negativi.
alex

21

Raccogliendo l'idea della tabella di ricerca di bta, puoi creare la tabella di ricerca con un blocco. I valori vengono generati al primo accesso e memorizzati per dopo:

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

Utilizzeresti naturalmente Integer#to_s(2), String#to_i(2)o "%b"in un vero programma, ma, se sei interessato a come funziona la traduzione, questo metodo calcola la rappresentazione binaria di un dato intero usando operatori di 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

Per verificare che funzioni:

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

Se lavori solo con le singole cifre 0-9, è probabilmente più veloce creare una tabella di ricerca in modo da non dover chiamare le funzioni di conversione ogni volta.

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'indicizzazione in questa tabella hash usando la rappresentazione di numeri interi o di stringhe di un numero produrrà la sua rappresentazione binaria come stringa.

Se si richiede che le stringhe binarie siano lunghe un determinato numero di cifre (mantenere gli zero iniziali), passare x.to_s(2)a sprintf "%04b", x(dove 4è il numero minimo di cifre da utilizzare).


@ bta- Sto codificando tutti questi caratteri in binario in modo da poterli usare in un algoritmo genetico. Mi piace molto l'idea di una tabella di ricerca per la codifica / decodifica poiché il set è limitato a 0..9 e + - * /
mcmaloney

2

Se stai cercando un metodo / classe Ruby, ho usato questo e ho incluso anche i test:

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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.