Я пытаюсь написать ветвящуюся функцию для возврата MAX или MIN двух целых чисел, не прибегая к if (или?:). Используя обычный метод, я могу сделать это достаточно легко для заданного размера слова:
inline int32 imax( int32 a, int32 b )
{
// signed for arithmetic shift
int32 mask = a - b;
// mask < 0 means MSB is 1.
return a + ( ( b - a ) & ( mask >> 31 ) );
}
Теперь, предполагая аргумент, что я действительно пишу вид приложения в виде процессора в порядке, где это необходимо, мой вопрос в том, есть ли способ использовать шаблоны С++, чтобы обобщить это на все размеры int.
Шаг → 31 работает, конечно, только для int32, и, хотя я могу копировать перегрузки в функции для int8, int16 и int64, кажется, что я должен использовать функцию шаблона вместо. Но как получить размер аргумента шаблона в битах?
Есть ли лучший способ сделать это, чем это? Могу ли я заставить маску T подписаться? Если T без знака, шаг смены маски не будет работать (потому что это будет скорее логический, чем арифметический сдвиг).
template< typename T >
inline T imax( T a, T b )
{
// how can I force this T to be signed?
T mask = a - b;
// I hope the compiler turns the math below into an immediate constant!
mask = mask >> ( (sizeof(T) * 8) - 1 );
return a + ( ( b - a ) & mask );
}
И, выполнив вышеуказанное, могу ли я предотвратить его использование для чего-либо, кроме целочисленного типа (например, без поплавков или классов)?