Main Content

Use of Shifts by C Code Generation Products

Introduction to Shifts by Code Generation Products

MATLAB® Coder™, Simulink® Coder, and Embedded Coder® generate C code that uses the C language’s shift left << and shift right >> operators. Modern C compilers provide consistent behavior for shift operators. However, some behaviors of the shift operators are not fully defined by some C standards. When you work with The MathWorks® code generation products, you need to know how to manage the use of C shifts.

Two’s Complement

Two’s complement is a way to interpret a binary number. Most modern processors represent integers using two’s complement. MathWorks® code generation products require C and C++ compilers to represent signed integers using two's complement. MathWorks toolboxes and documentation use two’s complement representation exclusively.

Arithmetic and Logical Shifts

The primary difference between an arithmetic shift and a logical shift is intent. Arithmetic shifts have a mathematical meaning. The intent of logical shifts is to move bits around, making them useful only for unsigned integers being used as collections of bit flags.

The C language does not distinguish between arithmetic and logical shifts and provides only one set of shift operators. When MathWorks code generation products use shifts on signed integers in generated code, the intent is always an arithmetic shift. For unsigned integers, there is no detectable difference in behavior between logical and arithmetic shifts.

Arithmetic Left-Shifts

An arithmetic left-shift represents multiplication by a power of 2.

a << b = a*2^b

If the value produced by multiplying by 2^b is too big, then an overflow occurs. In case of an overflow, the ideal answer wraps around modulo 2^n to fit in the data type. The C90 standard specifies left-shift behavior. At the bit level, b of the bits are shifted off the left end and discarded. At the right end, b bits of value 0 are shifted in. The standard does not specify a difference between unsigned and signed. For both unsigned and two's complement signed, the bit level behavior provides the intended arithmetic left-shift behavior.

The C99 standard describes the arithmetic interpretation. It also states that for signed types, the behavior is undefined for any negative value or for a positive value that would overflow. A compiler vendor might exploit the C99 standard undefined behavior clause to optimize code in a way that changes the behavior intended by the coder. If your compiler is C99-compliant but not C90-compliant, then turn off the option Replace multiplications by powers of two with signed bitwise shifts (Embedded Coder). Older C++ standards follow the C90 standard with regard to shift left. Newer C++ standards are similar to the C99 standard.

Arithmetic Right-Shifts

An arithmetic right-shift represents division by a power of 2, where the ideal quotient rounds to floor.

a >> b = a/2^b

When a is nonnegative, the C standards state that right-shift must provide this arithmetic behavior. If a is signed and negative, then the standard states that the implementation defines the behavior. The C standard requires that compilers document their implementation behavior. Nearly all compilers implement signed shift right as an arithmetic shift that rounds to floor. This is the simplest and most efficient behavior for the compiler vendor to provide. If you have a compiler that does not provide arithmetic right-shift, or your coding standards do not allow you to use signed right-shift, then you can select options that avoid signed shift right. For example, Allow right shifts on signed integers (Embedded Coder) replaces signed right shifts with a function call.

Out-of-Range Shifts

In C, when shifting an integer of word length n, use a shift amount between 0 and n – 1, inclusive. The C standard does not define shifting by other amounts, such as:

  • Shifting by a negative constant.

  • Shifting by an amount greater than word length.

When the shift amount is constant, the products do not generate out-of-range shifts. The risk of out-of-range shifts comes from explicitly modeled shifts where the shift amount is a non constant variable. When modeling shifts with variable shift amounts, make sure that the shift amount is always in range.

Modeling Sources of Shifts

There are explicit and implicit sources of shifts in models and algorithms.

Explicit

Implicit

  • Fixed-point operations that involve a scaling change

    When converting fixed-point scaling, if the net slope change is not an exact power of two, then a multiplication followed by a shift approximates the ideal net slope. For more information on net slope computation, see Handle Net Slope Computation.

  • Underlying higher-level algorithms (for example, FFT algorithms)

Controlling Shifts in Generated Code

Several configuration parameters have an effect on the number and style of shifts that appear in generated code.