Làm thế nào để bạn tạo số nguyên 0..9 và toán tử toán học + - * / trong chuỗi nhị phân. Ví dụ:
0 = 0000,
1 = 0001,
...
9 = 1001
Có cách nào để làm điều này với Ruby 1.8.6 mà không cần sử dụng thư viện không?
Làm thế nào để bạn tạo số nguyên 0..9 và toán tử toán học + - * / trong chuỗi nhị phân. Ví dụ:
0 = 0000,
1 = 0001,
...
9 = 1001
Có cách nào để làm điều này với Ruby 1.8.6 mà không cần sử dụng thư viện không?
Câu trả lời:
Bạn có Integer#to_s(base)
và String#to_i(base)
có sẵn cho bạn.
Integer#to_s(base)
chuyển đổi một số thập phân thành một chuỗi đại diện cho số trong cơ sở được chỉ định:
9.to_s(2) #=> "1001"
trong khi ngược lại thu được với String#to_i(base)
:
"1001".to_i(2) #=> 9
("%08b" % int)
hoặc ("%08b" % string)
trả về một số bit cố định.
-9.to_s(2)
=> "-1001"
Ai đó có thể giải thích điều này?
9
là 1001
trong nhị phân.
Tôi đã hỏi một câu hỏi tương tự . Dựa trên câu trả lời của @sawa , cách ngắn gọn nhất để biểu diễn một số nguyên trong một chuỗi ở định dạng nhị phân là sử dụng trình định dạng chuỗi:
"%b" % 245
=> "11110101"
Bạn cũng có thể chọn thời gian biểu diễn chuỗi là bao lâu, điều này có thể hữu ích nếu bạn muốn so sánh các số nhị phân có chiều rộng cố định:
1.upto(10).each { |n| puts "%04b" % n }
0001
0010
0011
0100
0101
0110
0111
1000
1001
1010
245.to_s(2)
sẽ nhanh hơn"%b" % 245
Chọn ý tưởng bảng tra cứu của bta, bạn có thể tạo bảng tra cứu với một khối. Các giá trị được tạo khi chúng được truy cập lần đầu và được lưu trữ sau này:
>> 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"}
Bạn tự nhiên sẽ sử dụng Integer#to_s(2)
, String#to_i(2)
hoặc "%b"
trong một chương trình thực tế, nhưng, nếu bạn đang quan tâm đến cách thức hoạt động dịch thuật, phương pháp này tính toán biểu diễn nhị phân của một số nguyên cho các nhà khai thác sử dụng cơ bản:
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
Để kiểm tra nó hoạt động:
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
Nếu bạn chỉ làm việc với các chữ số duy nhất 0-9, có thể nhanh hơn để tạo bảng tra cứu để bạn không phải gọi các hàm chuyển đổi mỗi lần.
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ập chỉ mục vào bảng băm này bằng cách sử dụng biểu diễn số nguyên hoặc chuỗi của một số sẽ mang lại biểu diễn nhị phân của nó dưới dạng chuỗi.
Nếu bạn yêu cầu các chuỗi nhị phân phải dài một số chữ số nhất định (giữ các số 0 đứng đầu), sau đó đổi x.to_s(2)
thành sprintf "%04b", x
(trong đó 4
số chữ số tối thiểu sẽ sử dụng).
Nếu bạn đang tìm kiếm một lớp / phương thức Ruby tôi đã sử dụng, và tôi cũng đã bao gồm các bài kiểm tra:
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