

5.17. Performing Bitlevel Operations on NumbersOccasionally we may need to operate on a Fixnum as a binary entity. This is less common in application level programming, but the need still arises. Ruby has a relatively full set of capabilities in this area. For convenience, numeric constants may be expressed in binary, octal, or hexadecimal. The usual operators AND, OR, XOR, and NOT are expressed by the Ruby operators &, , ^, and ~, respectively. x = 0377 # Octal (decimal 255) y = 0b00100110 # Binary (decimal 38) z = 0xBEEF # Hex (decimal 48879) a = x  z # 48895 (bitwise OR) b = x & z # 239 (bitwise AND) c = x ^ z # 48656 (bitwise XOR) d = ~ y # 39 (negation or 1's complement) The instance method size can be used to determine the word size of the specific architecture on which the program is running. bytes = 1.size # Returns 4 for one particular machine There are leftshift and rightshift operators (<< and >>, respectively). These are logical shift operations; they do not disturb the sign bit (though >> does propagate it). x = 8 y = 8 a = x >> 2 # 2 b = y >> 2 # 2 c = x << 2 # 32 d = y << 2 # 32 Of course, anything shifted far enough to result in a zero value will lose the sign bit because 0 is merely 0. Brackets can be used to treat numbers as arrays of bits. The 0th bit is the least significant bit regardless of the bit order (endianness) of the architecture. x = 5 # Same as 0b0101 a = x[0] # 1 b = x[1] # 0 c = x[2] # 1 d = x[3] # 0 # Etc. # 0 It is not possible to assign bits using this notation (because a Fixnum is stored as an immediate value rather than an object reference). However, you can always fake it by leftshifting a 1 to the specified bit position and then doing an OR or AND operation. # We can't do x[3] = 1 # but we can do: x = (1<<3) # We can't do x[4] = 0 # but we can do: x &= ~(1<<4) 

