diff options
Diffstat (limited to 'source/arduino/bitshift.rst')
-rw-r--r-- | source/arduino/bitshift.rst | 148 |
1 files changed, 83 insertions, 65 deletions
diff --git a/source/arduino/bitshift.rst b/source/arduino/bitshift.rst index f59b489..d849f2a 100644 --- a/source/arduino/bitshift.rst +++ b/source/arduino/bitshift.rst @@ -1,74 +1,76 @@ +.. highlight:: cpp + .. _arduino-bitshift: -bitshift left (<<), bitshift right (>>) -======================================= +Bit shift left (``<<``), bit shift right (``>>``) +================================================= Description ----------- -From *The Bitmath Tutorial* in The Playground - +(Adapted from `The Bit Math Tutorial +<http://www.arduino.cc/playground/Code/BitMath>`_ in `The Arduino +Playground <http://www.arduino.cc/playground/Main/HomePage>`_\ ) There are two bit shift operators in C++: the left shift operator -<< and the right shift operator >>. These operators cause the bits -in the left operand to be shifted left or right by the number of +``<<`` and the right shift operator ``>>``. These operators cause the +bits in the left operand to be shifted left or right by the number of positions specified by the right operand. -More on bitwise math may be found -`here. <http://www.arduino.cc/playground/Code/BitMath>`_ +More information on bitwise math can be obtained in the Wikipedia +article on `bitwise operations +<http://en.wikipedia.org/wiki/Bitwise_operation>`_\ , especially the +section on shifts in `C, C++, and Java +<http://en.wikipedia.org/wiki/Bitwise_operation#Shifts_in_C.2C_C.2B.2B.2C_C.23_and_Java>`_\ . Syntax ------ -variable << number\_of\_bits - - - -variable >> number\_of\_bits +``some_int << number_of_bits`` +``some_int >> number_of_bits`` Parameters ---------- -variable - (byte, int, long) number\_of\_bits integer <= 32 +* **some_int** An integer value or variable. + +* **number_of_bits** integer whose value is at most ``8 * + sizeof(variable)`` (so ``number_of_bits`` can be at most 32 for + ``int`` values, at most ``8`` for ``char`` values, etc.; the various + integer sizes are summarized :ref:`in this table + <arduino-arithmetic-int-sizes>`\ ). Example: -------- -:: - - int a = 5; // binary: 0000000000000101 - int b = a << 3; // binary: 0000000000101000, or 40 in decimal - int c = b >> 3; // binary: 0000000000000101, or back to 5 like we started with - - - -When you shift a value x by y bits (x << y), the leftmost y bits in -x are lost, literally shifted out of existence: - +Here are some examples of bit shifting, with the binary representation of the number in comments:: + int a = 5; // binary: 101 + int b = a << 3; // binary: 101000, or 40 in decimal + int c = b >> 3; // binary: 101, or back to 5 like we started with -:: - int a = 5; // binary: 0000000000000101 - int b = a << 14; // binary: 0100000000000000 - the first 1 in 101 was discarded +When you left shift a value x by y bits (x << y), the leftmost y bits +in x are lost, literally shifted out of existence. We'll do this +example with ``char`` values (which are integers in the range 0-255, +and take up 8 bits of memory):: + char a = 5; // binary (all 8 bits): 00000101 + char b = a << 7; // binary: 10000000 - the first 1 in 101 was discarded -If you are certain that none of the ones in a value are being -shifted into oblivion, a simple way to think of the left-shift -operator is that it multiplies the left operand by 2 raised to the -right operand power. For example, to generate powers of 2, the -following expressions can be employed: - - - -:: +If you are certain that none of the ones in a value are being shifted +into oblivion, a simple way to think of the left-shift operator is +that it multiplies the left operand by 2 raised to the right operand +power (in math notation, ``x << y`` equals x * 2\ :sup:`y`\ , as long +as none of the bits of x get shifted out). For example, to generate +powers of 2, the following expressions can be employed:: 1 << 0 == 1 1 << 1 == 2 @@ -80,48 +82,64 @@ following expressions can be employed: 1 << 10 == 1024 ... +.. _arduino-bitshift-signbit-gotcha: +When you shift x right by y bits (``x >> y``), and the highest bit in +x is a 1, the behavior depends on the exact data type of x. If x is of +type ``int``, the highest bit is special, and determines whether x is +negative or not; the details are too complicated to explain here, but +they are thoroughly explained in the Wikipedia article on `two's +complement arithmetic +<http://en.wikipedia.org/wiki/Two%27s_complement>`_\ , which the +system most computers use to store integers. In that case, the sign +bit is copied into lower bits, for esoteric historical reasons:: -When you shift x right by y bits (x >> y), and the highest bit in x -is a 1, the behavior depends on the exact data type of x. If x is -of type int, the highest bit is the sign bit, determining whether x -is negative or not, as we have discussed above. In that case, the -sign bit is copied into lower bits, for esoteric historical -reasons: - - - -:: + int x = -16; // binary (all 32 bits): 11111111111111111111111111110000 + int y = x >> 3; // binary: 11111111111111111111111111111110 - int x = -16; // binary: 1111111111110000 - int y = x >> 3; // binary: 1111111111111110 +This behavior, called "sign extension", is often not what you +want. You probably wish zeros to be shifted in from the left. It +turns out that the right shift rules are different for ``unsigned +int`` values, so you can use a type cast to suppress ones being copied +from the left:: -This behavior, called sign extension, is often not the behavior you -want. Instead, you may wish zeros to be shifted in from the left. -It turns out that the right shift rules are different for unsigned -int expressions, so you can use a typecast to suppress ones being -copied from the left: + int x = -16; // binary: 11111111111111111111111111110000 + int y = (unsigned int)x >> 3; // binary: 00011111111111111111111111111110 -:: - - int x = -16; // binary: 1111111111110000 - int y = (unsigned int)x >> 3; // binary: 0001111111111110 +If you are careful to avoid sign extension, you can use the +right-shift operator, ``>>``, as a way to divide by powers of 2. For +example:: + int x = 1000; + int y = x >> 3; // integer division of 1000 by 8, causing y = 125. -If you are careful to avoid sign extension, you can use the -right-shift operator >> as a way to divide by powers of 2. For -example: +Arduino Compatibility +--------------------- +Since it's part of the C++ language, bit shifting on the Maple is +compatible with the Arduino; however, you should keep in mind that the +Maple has bigger integer types (as in, more bits) than the Arduino. +Since the STM32 is a 32-bit processor, the ``int`` type takes up 32 +bits instead of 16, like on Arduino's 16-bit microcontroller. This +means that you can shift left, like ``x << y``, with bigger values of +``y`` on the Maple before ones in ``x`` start to get shifted out. -:: - - int x = 1000; - int y = x >> 3; // integer division of 1000 by 8, causing y = 125. +To calculate the number of bits of an integer type on the Maple, +multiply its size in bytes (see :ref:`this table +<arduino-arithmetic-int-sizes>` for these) by 8, since there are 8 +bits in 1 byte. For example, a ``short`` takes up 2 bytes of memory, +or 2 * 8 = 16 bits. +See Also +-------- +- :ref:`arduino-bit` +- :ref:`arduino-bitread` +- :ref:`arduino-bitwrite` +- :ref:`arduino-bitclear` |