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 не определяет смещение на другие суммы, такие как:
Сдвиг на отрицательную константу.
Смещение на величину, превышающую длину слова.
Когда величина сдвига постоянна, продукты не генерируют смещения вне диапазона. Риск смещения вне диапазона исходит из явно смоделированных сдвигов, где величина сдвига является непостоянной переменной. При моделировании смен с переменными значениями смещения убедитесь, что величина смещения всегда находится в диапазоне.
Существуют явные и неявные источники сдвигов в моделях и алгоритмах.
Явный
Неявный
Операции с фиксированной точкой, связанные с изменением масштаба
При преобразовании масштабирования с фиксированной точкой, если изменение чистого уклона не является точной степенью двух, то умножение, за которым следует сдвиг, аппроксимирует идеальный чистый наклон. Дополнительные сведения о вычислении чистого откоса см. в разделе Обработка вычисления чистого откоса.
Базовые алгоритмы более высокого уровня (например, алгоритмы БПФ)
Несколько параметров конфигурации влияют на количество и стиль смен, появляющихся в сгенерированном коде.
Подписанные целочисленные раунды деления на
Задайте для этого параметра значение Floor или Zero во избежание создания дополнительного кода.
Использовать деление для расчета чистого уклона с фиксированной точкой
Если этот параметр включен, то вместо умножения используется деление, за которым следуют сдвиги для вычисления чистого уклона с фиксированной точкой.
Замена умножения на степени двух со знаком побитовых сдвигов (встроенный кодер)
Когда этот параметр включен, умножения на степени двух заменяются на побитовые сдвиги со знаком. Очистка этого параметра поддерживает соответствие MISRA C ®.
Разрешить правые сдвиги для подписанных целых чисел (встроенный кодер)
Если этот параметр включен, сгенерированный код может содержать правые побитовые сдвиги для целых чисел со знаком. Чтобы предотвратить правые побитовые сдвиги для подписанных целых чисел, снимите этот флажок.
Сдвиг вправо на целое число со знаком как арифметический сдвиг
Выберите этот параметр, если компилятор C реализует в качестве арифметического правого сдвига целочисленный сдвиг со знаком.