В ARM у вас уже может быть встроенная насыщенная арифметика. DSP-расширения ARMv5 могут насыщать регистры любой битовой длины. Также на ARM насыщение обычно дешево, потому что большинство инструкций можно извинить условно.
ARMv6 даже имеет насыщенное сложение, вычитание и все остальное для 32-битных и упакованных чисел.
На x86 вы получаете насыщенную арифметику через MMX или SSE.
Все это требует ассемблера, так что это не то, что вы просили.
Также есть C-трюки для выполнения насыщенной арифметики. Этот маленький код делает насыщенное сложение на четыре байта меча. Он основан на идее параллельного вычисления 32 полумесяцев, например, добавление чисел без переноса
Это делается первым. Затем переносы вычисляются, добавляются и заменяются маской, если сложение будет переполнено.
uint32_t SatAddUnsigned8(uint32_t x, uint32_t y)
{
uint32_t signmask = 0x80808080;
uint32_t t0 = (y ^ x) & signmask;
uint32_t t1 = (y & x) & signmask;
x &= ~signmask;
y &= ~signmask;
x += y;
t1 |= t0 & x;
t1 = (t1 << 1) - (t1 >> 7);
return (x ^ t0) | t1;
}
Вы можете получить то же самое для 16 битов (или любого вида битового поля), изменив константу маски знака и сдвиги внизу, например:
uint32_t SatAddUnsigned16(uint32_t x, uint32_t y)
{
uint32_t signmask = 0x80008000;
uint32_t t0 = (y ^ x) & signmask;
uint32_t t1 = (y & x) & signmask;
x &= ~signmask;
y &= ~signmask;
x += y;
t1 |= t0 & x;
t1 = (t1 << 1) - (t1 >> 15);
return (x ^ t0) | t1;
}
uint32_t SatAddUnsigned32 (uint32_t x, uint32_t y)
{
uint32_t signmask = 0x80000000;
uint32_t t0 = (y ^ x) & signmask;
uint32_t t1 = (y & x) & signmask;
x &= ~signmask;
y &= ~signmask;
x += y;
t1 |= t0 & x;
t1 = (t1 << 1) - (t1 >> 31);
return (x ^ t0) | t1;
}
Выше код делает то же самое для 16 и 32-битных значений.
Если вам не нужна функция добавления функций и параллельного насыщения нескольких значений, просто замаскируйте нужные биты. В ARM вы также хотите изменить константу маски маски, потому что ARM не может загрузить все возможные 32-битные константы за один цикл.
Редактировать: Скорее всего, параллельные версии медленнее, чем прямые методы, но они быстрее, если вам нужно насыщать более одного значения за раз.