#c #arm #integer-arithmetic #cmsis
Вопрос:
Я наткнулся на код, подобный этому, в библиотеке ARM CMSIS-NN:
int32_t val, shift;
// code that initializes val and shift
int32_t result = val * (1 << shift);
которая направлена на умножение val
на некоторую степень двух значений x
, shift
являющуюся показателем степени, т. Е. x=pow(2,shift)
. Почему они просто не меняются? Вот так
int32_t result = val << shift;
Есть ли что-то особенное, чего мне не хватает? Может ли компилятор каким-то особым образом оптимизировать предыдущую операцию?
ПРАВКА: Что меня смущает, так это то, что они используют «простые сдвиги» по всему коду. Кроме того, код должен быть сильно оптимизирован. Но я думаю, что современные компиляторы сами поймут, что сдвиг-это правильный путь (вместо умножения)?
Комментарии:
1. Что это за тип
q31_t
? Вы уверены, что он поддерживает<<
оператора? Например, типы с плавающей запятой этого не делают.2. Сдвиг ограничен количеством битов в машинном слове. Pow () — это не так. [это ограничение, вероятно, было вызвано ограничением в инструкциях x86, где сдвиг рассматривался как (сдвиг 2) ]
3. @Nate Элдридж
q31_t
-это тип данных с фиксированной точкой (см. Здесь en.wikipedia.org/wiki/Q_(number_format) ). В CMSIS-NN это просто typedef для int32_t-4. @wildplasser все переменные (включая результат) являются 32-битными. Так что здесь это не должно иметь значения, верно?
5. Кстати: вы всегда должны выполнять такие сдвиги в самом большом доступном типе данных без знака:
(1ull <<shift)
Да, это может иметь значение, вы можете попытаться сдвинуться на 33, и результат будет неопределенным.
Ответ №1:
Он всегда правильно подписывается и заставляет использовать соответствующие инструкции FPU и работает с любыми типами данных.
Комментарии:
1. Я должен был упомянуть, что все это арифметика с фиксированной точкой. Таким образом, здесь задействованы только целые числа (если быть точным, int32_t). Но сохранение знака может быть причиной. Таким образом, начальный бит не будет смещен, верно? Спасибо, что указали на это. Я должен подумать об этом еще немного.
2. @fabian не только исправил
3. что вы имеете в виду под этим?
4. они хотели быть агностиками типа
5. Но зачем им быть агностиками типов, если все типы привязаны к int32_t?