Использование сдвигов продуктами генерации кода C

Введение в сдвиги по продуктам генерации кода

MATLAB® Coder™, Simulink® Кодер и Embedded Coder® сгенерировать код С, который использует операторы shift left на C языке < < и shift right > >. Современные компиляторы C обеспечивают согласованное поведение операторов shift. Однако некоторые виды поведения операторов сдвига не полностью определены некоторыми стандартами C. Когда вы работаете с The MathWorks® продукты генерации кода, вам нужно знать, как управлять использованием сдвигов.

Дополнение двоих

Дополнение двух является способом интерпретации двоичного числа. Большинство современных процессоров представляют целые числа, используя дополнение двух. MathWorks® продукты генерации кода требуют, чтобы компиляторы C и C++ представляли целые числа со знаком, используя дополнение двух. Тулбоксы и документация MathWorks используют представление двух комплементов исключительно.

Арифметические и логические сдвиги

Основное различие между арифметическим сдвигом и логическим сдвигом является намерением. Арифметические сдвиги имеют математический смысл. Цель логических сдвигов состоит в том, чтобы перемещать биты вокруг, что делает их полезными только для беззнаковых целых чисел, используемых в качестве наборов битовых флагов.

Язык C не различает арифметические и логические сдвиги и предоставляет только один набор операторов сдвига. Когда продукты генерации кода MathWorks используют сдвиги на подписанных целых числах в сгенерированном коде, намерение всегда является арифметическим сдвигом. Для беззнаковых целых чисел нет обнаруживаемого различия в поведении между логическим и арифметическим сдвигами.

Арифметические сдвиги влево

Арифметический сдвиг влево представляет умножение на степень 2.

a << b = a*2^b

Если значение, полученное умножением на 2 ^ b, слишком велико, то происходит переполнение. В случае переполнения идеальный ответ переносов вокруг по модулю 2 ^ n, чтобы соответствовать типу данных. Стандарт C90 задает поведение слева. На уровне битов b из бит смещаются с левого конца и отбрасываются. На правом конце < reservedrangesplaceholder0 > бит значения 0 сдвинуты. Стандарт не определяет различие между неподписанным и подписанным. Для обоих неподписанных и двух комплементов со знаком, поведение на битовом уровне обеспечивает предполагаемое арифметическое поведение слева-сдвига.

Стандарт C99 описывает арифметическую интерпретацию. В нем также указывается, что для подписанных типов поведение не определено для любого отрицательного значения или для положительного значения, которое переполнено. Поставщик компилятора может использовать C99 стандартное предложение неопределенного поведения, чтобы оптимизировать код таким образом, чтобы изменить поведение, задуманное кодером. Если ваш компилятор C99-compliant, но не C90-compliant, отключите опцию Заменить умножения на степени двойки со знаковыми побитовыми сдвигами (Embedded Coder). Старые стандарты C++ соответствуют C90 стандарту в отношении смены налево. Более новые стандарты C++ аналогичны C99 стандарту.

Арифметические правые сдвиги

Арифметический сдвиг вправо представляет деление на степень 2, где идеальный частный округляет в пол.

a >> b = a/2^b

Когда a неотрицательна, стандарты C заявляют, что правый сдвиг должен обеспечить это арифметическое поведение. Если a подписан и отрицателен, то стандарт утверждает, что реализация определяет поведение. Стандарт C требует, чтобы компиляторы документировали поведение их реализации. Почти все компиляторы реализуют сдвиг со знаком вправо как арифметический сдвиг, который округляется до этажа. Это самое простое и эффективное поведение для поставщика компилятора. Если у вас есть компилятор, который не предоставляет арифметический right-shift, или ваши стандарты кодирования не позволяют вам использовать signed right-shift, то можно выбрать опции, которые избегают signed shift right. Для примера Allow right сдвигов on signed целых чисел (Embedded Coder) заменяет signed right сдвигов на вызов функции.

Сдвиги вне области допустимого значения

В C при сдвиге целого числа < reservedrangesplaceholder1 > размеры слова используйте величину сдвига между 0 и n - 1 включительно. Стандарт C не определяет перемену на другие суммы, такие как:

  • Смещение на отрицательную константу.

  • Смещение на величину, большую, чем размер слова.

Когда величина сдвига постоянна, продукты не генерируют сдвиги вне области допустимого. Риск сдвигов вне области значений исходит из явно смоделированных сдвигов, где величина сдвига является непостоянной переменной. При моделировании сдвигов с переменными суммами сдвига убедитесь, что величина сдвига всегда находится в области значений.

Источники сдвигов в моделировании

Существуют явные и неявные источники сдвигов в моделях и алгоритмах.

Явный

Неявный

  • Операции с фиксированной точкой, которые включают изменение масштаба

    При преобразовании масштабирования с фиксированной точкой, если изменение наклона сети не является точной степенью двойки, то умножение, за которым следует сдвиг, аппроксимирует идеальный наклон сети. Для получения дополнительной информации о расчете уклона сети см. Указатель Расчета уклона сети.

  • Базовые алгоритмы более высокого уровня (для примера, БПФ алгоритмов)

Управление сдвигами в сгенерированном коде

Несколько параметров конфигурации влияют на количество и стиль сдвигов, которые появляются в сгенерированном коде.

Для просмотра документации необходимо авторизоваться на сайте