2010-02-26 3 views
138

Come si creano numeri interi 0..9 e operatori matematici + - */in stringhe binarie. Per esempio:Come convertire una stringa o un intero in binario in Ruby?

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

C'è un modo per farlo con Ruby 1.8.6 senza l'utilizzo di una libreria?

+0

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

+0

Immagino che tu volessi fare la famosa cosa dell'algoritmo genetico? :-) – nemesisfixx

risposta

296

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

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

Questo mi ha salvato la giornata! –

+17

@TomRavenscroft Inoltre, è possibile usare '("% 08b "% int)' o '("% 08b "% string)' per restituire un numero fisso di bit. – decay

+1

Brilliant Mike, Brilliant Ruby! –

4

Se si lavora solo con il cifre singole 0-9, è probabile che sia più veloce costruire 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" 

indicizzazione in questa tabella hash utilizzando l'intero o rappresentazione stringa di un numero produrrà sua rappresentazione binaria come stringa.

Se si richiede le stringhe binarie per essere un certo numero di cifre lunghe (mantenere zeri iniziali), quindi modificare x.to_s(2)-sprintf "%04b", x (dove 4 è il numero minimo di cifre da utilizzare).

+0

@ bta- Sto codificando tutti questi caratteri in binario in modo da poterli utilizzare 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

19

Riprendendo l'idea della tabella di ricerca di bta, è possibile creare la tabella di ricerca con un blocco. I valori vengono generati al momento del primo accesso e memorizzati per la successiva:

>> 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"} 
2

Se siete alla ricerca di una classe/metodo di Rubino ho usato questo, e mi hanno 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 
8

È sarebbe naturalmente utilizzare Integer#to_s(2), String#to_i(2) o "%b" in un programma vero e proprio, ma, se siete interessati a come funziona la traduzione, questo metodo calcola la rappresentazione binaria di un dato intero utilizzando gli 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 controllare funziona:

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 
32

ho chiesto a similar question. Sulla base di @sawa 's risposta, il modo più succinto per rappresentare un intero in una stringa in formato binario è quello di utilizzare il formattatore stringa:

"%b" % 245 
=> "11110101" 

è anche possibile scegliere per quanto tempo la rappresentazione di stringa di essere, che potrebbe essere utile se vuoi confrontare i 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 qualche test locale per convertire gli interi in stringa binaria, ma il risultato mostra che i codici come ' 245.to_s (2) 'sarà più veloce di' "% b"% 245' –