This week some students come up with solutions using or appropriate to use bitwise operations, so, it is time to refresh the memory about that subject.
Binary numbers are just a bunch of Zeroes and Ones.
Representing: true / false; on / off, the base of the computer science.
Some Powers of Two:
power of 2 base-10 base-2 (binary)
20 1 1
21 2 10
22 4 100
23 8 1000
...
29 512 1000000000
210 1024 10000000000
211 2048 100000000000
212 4096 1000000000000
...
Binary numbers:
23 = 16 + 0 + 4 + 2 + 1
1 0 1 1 1 = 10111
252 = 128 + 64 + 32 + 16 + 8 + 4 + 0 + 0
1 1 1 1 1 1 0 0 = 11111100
Binary numbers in Ruby:
bin_num1 = 0b10111
bin_num1 = 0b11111100
The bitwise operations in Ruby:
bin1 = 0b100011010101
bin2 = 0b101010000010
puts '- - - - - - - - - - - - - - - - - - - - - - - - -'
puts ' = the bitwise or operation ='
puts '100011010101 <- bin1'
puts '101010000010 <- bin2'
puts '------------------ |'
bin_result = bin1 | bin2
puts sprintf("%12b", bin_result)
puts '- - - - - - - - - - - - - - - - - - - - - - - - -'
puts ' = the bitwise and operation ='
puts '100011010101 <- bin1'
puts '101010000010 <- bin2'
puts '------------------ &'
bin_result = bin1 & bin2
puts sprintf("%12b", bin_result)
puts '- - - - - - - - - - - - - - - - - - - - - - - - -'
puts '= the bitwise exclusive or operation ='
puts '100011010101 <- bin1'
puts '101010000010 <- bin2'
puts '------------------ ^'
bin_result = bin1 ^ bin2
puts sprintf("%12b", bin_result)
puts '- - - - - - - - - - - - - - - - - - - - - - - - -'
puts '= the bitwise negation operation ='
puts '100011010101 <- bin1'
puts '------------------ ~'
bin_result = ~bin1
puts sprintf("%12b", bin_result)
puts '^'
puts '|'
puts '+----- Ruby would like to print 1s forever here'
puts '- - - - - - - - - - - - - - - - - - - - - - - - -'
puts '= the bitwise left shift operation ='
puts '101010000010 <- bin2'
puts '------------------ <<'
bin_result = bin2 << 3
puts sprintf("%12b", bin_result)
puts '- - - - - - - - - - - - - - - - - - - - - - - - -'
puts '= the bitwise right shift operation ='
puts '101010000010 <- bin2'
puts '------------------ >>'
bin_result = bin2 >> 5
puts sprintf("%12b", bin_result)
Parity Check:
It is the easiest way to check if a number is odd or even.
Check the least-significant bit (one's place) in the binary representation:
If it is 0 then the number is even
If it is 1 then the number is odd
def odd_even(number)
puts "#{number.to_s} is #{number & 1 == 1 ? 'odd' : 'even'}"
end
odd_even(8)
odd_even(-3)
odd_even(104)
odd_even(127)
odd_even(32)
odd_even(51)
“Powerful” Bit Operations:
Observe:
11 00001011
22 00010110
44 00101100
If we “shift” the bits one place to the left, and add a 0 at the last place, we double the number.
A final example:
We want to know if a string has just words and spaces, no numbers or special characters:
class String
def are_just_words?
is_false = 0b0
self.split('').collect { |character|
is_false = is_false | ((' '.eql? character or
(65..90).include? eval("?#{character}") or
(97..122).include? eval("?#{character}") or
(192..255).include? eval("?#{character}"))? 0b0 : 0b1)
}
is_false == 0b0 ? true : false
end
end
puts 'Atenção eloqüente ortográfico filosófico'.are_just_words?
Returns true
Now try to include numbers and / or special characters and see what happens.