This topic shows how to use bit-wise operations in MATLAB® to manipulate the bits of numbers. Operating on bits is directly supported by most modern CPUs. In many cases, manipulating the bits of a number in this way is quicker than performing arithmetic operations like division or multiplication.
Any number can be represented with bits (also known as binary digits). The binary, or base 2, form of a number contains 1s and 0s to indicate which powers of 2 are present in the number. For example, the 8-bit binary form of 7 is
A collection of 8 bits is also called 1 byte. In binary representations, the bits are counted from the right to the left, so the first bit in this representation is a 1. This number represents 7 because
When you type numbers into MATLAB, it assumes the numbers are double precision (a 64-bit binary representation). However, you can also specify single-precision numbers (32-bit binary representation) and integers (signed or unsigned, from 8 to 64 bits). For example, the most memory efficient way to store the number 7 is with an 8-bit unsigned integer:
a = uint8(7)
a = uint8 7
You can even specify the binary form directly using the prefix
0b followed by the binary digits (for more information, see Hexadecimal and Binary Values). MATLAB stores the number in an integer format with the fewest number of bits. Instead of specifying all the bits, you need to specify only the left-most 1 and all the digits to the right of it. The bits to the left of that bit are trivially zero. So the number 7 is:
b = 0b111
b = uint8 7
MATLAB stores negative integers using two's complement. For example, consider the 8-bit signed integer -8. To find the two's complement bit pattern for this number:
Start with the bit pattern of the positive version of the number, 8:
Next, flip all of the bits:
Finally, add 1 to the result:
11111000, is the bit pattern for -8:
n = 0b11111000s8
n = int8 -8
MATLAB does not natively display the binary format of numbers. For that, you can use the
dec2bin function, which returns a character vector of binary digits for positive integers. Again, this function returns only the digits that are not trivially zero.
ans = '111'
You can use
bin2dec to switch between the two formats. For example, you can convert the binary digits
10110101 to decimal format with the commands
data = [1 0 1 1 0 1 0 1]; dec = bin2dec(num2str(data))
dec = 181
typecast functions are also useful to switch among different data types. These functions are similar, but they differ in how they treat the underlying storage of the number:
Because MATLAB does not display the digits of a binary number directly, you must pay attention to data types when you work with bit-wise operations. Some functions return binary digits as a character vector (
dec2bin), some return the decimal number (
bitand), and others return a vector of the bits themselves (
MATLAB has several functions that enable you to perform logical operations on the bits of two equal-length binary representations of numbers, known as bit masking:
bitand — If both digits are 1, then the resulting digit is also a 1. Otherwise, the resulting digit is 0.
bitor — If either digit is 1, then the resulting digit is also a 1. Otherwise, the resulting digit is 0.
bitxor — If the digits are different, then the resulting digit is a 1. Otherwise, the resulting digit is 0.
In addition to these functions, the bit-wise complement is available with
bitcmp, but this is a unary operation that flips the bits in only one number at a time.
One use of bit masking is to query the status of a particular bit. For example, if you use a bit-wise AND operation with the binary number
00001000, you can query the status of the fourth bit. You can then shift that bit to the first position so that MATLAB returns a 0 or 1 (the next section describes bit shifting in more detail).
n = 0b10111001; n4 = bitand(n,0b1000); n4 = bitshift(n4,-3)
n4 = uint8 1
Bit-wise operations can have surprising applications. For example, consider the 8-bit binary representation of the number :
8 is a power of 2, so its binary representation contains a single 1. Now consider the number :
By subtracting 1, all of the bits starting at the right-most 1 are flipped. As a result, when is a power of 2, corresponding digits of and are always different, and the bit-wise AND returns zero.
n = 0b1000; bitand(n,n-1)
ans = uint8 0
However, when is not a power of 2, then the right-most 1 is for the bit, so and have all the same bits except for the bit. For this case, the bit-wise AND returns a nonzero number.
n = 0b101; bitand(n,n-1)
ans = uint8 4
This operation suggests a simple function that operates on the bits of a given input number to check whether the number is a power of 2:
function tf = isPowerOfTwo(n) tf = n && ~bitand(n,n-1); end
The use of the short-circuit AND operator
&& checks to make sure that
n is not zero. If it is, then the function does not need to calculate
bitand(n,n-1) to know that the correct answer is
Because bit-wise logical operations compare corresponding bits in two numbers, it is useful to be able to move the bits around to change which bits are compared. You can use
bitshift to perform this operation:
bitshift(A,N) shifts the bits of
A to the left by
N digits. This is equivalent to multiplying
A by .
bitshift(A,-N) shifts the bits of
A to the right by
N digits. This is equivalent to dividing
A by .
These operations are sometimes written
A<<N (left shift) and
A>>N (right shift), but MATLAB does not use
>> operators for this purpose.
When the bits of a number are shifted, some bits fall off the end of the number, and
1s are introduced to fill in the newly created space. When you shift bits to the left, the bits are filled in on the right; when you shift bits to the right, the bits are filled in on the left.
For example, if you shift the bits of the number 8 (binary:
1000) to the right by one digit, you get 4 (binary:
n = 0b1000; bitshift(n,-1)
ans = uint8 4
Similarly, if you shift the number 15 (binary:
1111) to the left by two digits, you get 60 (binary:
n = 0b1111; bitshift(15,2)
ans = 60
When you shift the bits of a negative number,
bitshift preserves the signed bit. For example, if you shift the signed integer -3 (binary:
11111101) to the right by 2 digits, you get -1 (binary:
11111111). In these cases,
bitshift fills in on the left with
1s rather than
n = 0b11111101s8; bitshift(n,-2)
ans = int8 -1
You can use the
bitset function to change the bits in a number. For example, change the first bit of the number 8 to a 1 (which adds 1 to the number):
ans = 9
bitset flips bits to on or 1. You can optionally use the third input argument to specify the bit value.
bitset does not change multiple bits at once, so you need to use a
for loop to change multiple bits. Therefore, the bits you change can be either consecutive or nonconsecutive. For example, change the first two bits of the binary number
bits = [1 2]; c = 0b1000; for k = 1:numel(bits) c = bitset(c,bits(k)); end dec2bin(c)
ans = '1011'
Another common use of
bitset is to convert a vector of binary digits into decimal format. For example, use a loop to set the individual bits of the integer
data = [1 1 0 0 1 1 0 1]; n = length(data); dec = 0b0u8; for k = 1:n dec = bitset(dec,n+1-k,data(k)); end dec
dec = uint8 205
ans = '11001101'
Another use of bit shifting is to isolate consecutive sections of bits. For example, read the last four bits in the 16-bit number
0110000010100000. Recall that the last four bits are on the left of the binary representation.
n = 0b0110000010100000; dec2bin(bitshift(n,-12))
ans = '110'
To isolate consecutive bits in the middle of the number, you can combine the use of bit shifting with logical masking. For example, to extract the 13th and 14th bits, you can shift the bits to the right by 12 and then mask the resulting four bits with
0011. Because the inputs to
bitand must be the same integer data type, you can specify
0011 as an unsigned 16-bit integer with
0b11u16. Without the
-u16 suffix, MATLAB stores the number as an unsigned 8-bit integer.
m = 0b11u16; dec2bin(bitand(bitshift(n,-12),m))
ans = '10'
Another way to read consecutive bits is with
bitget, which reads specified bits from a number. You can use colon notation to specify several consecutive bits to read. For example, read the last 8 bits of
ans = 1x9 uint16 row vector 0 1 1 0 0 0 0 0 1
You can also use
bitget to read bits from a number when the bits are not next to each other. For example, read the 5th, 8th, and 14th bits from
bits = [14 8 5]; bitget(n,bits)
ans = 1x3 uint16 row vector 1 1 0