exponenta event banner

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

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

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

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

Дополнение Two - это способ интерпретировать двоичное число. Большинство современных процессоров представляют целые числа, используя два дополнения. Продукты для генерации кода MathWorks ® требуют, чтобы компиляторы C и C++ представляли подписанные целые числа с помощью дополнения two. В панелях инструментов и документации MathWorks используются только два представления дополнений.

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

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

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

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

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

a << b = a*2^b

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

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

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

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

a >> b = a/2^b

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

Смещения вне диапазона

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

  • Сдвиг на отрицательную константу.

  • Смещение на величину, превышающую длину слова.

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

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

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

Явный

  • Функции битового сдвига MATLAB: bitsll, bitsra, bitsrl, bitshift

  • Арифметический блок сдвига Simulink

  • Побитовые операции Stateflow ®

Неявный

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

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

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

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

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