пятница, 16 декабря 2011 г.

Число. Обрезать до байта? Быстро? Легко!

Когда выполняются вычисления на графических картах (GPU), создаются текстуры, или, например, данные готовятся к серилизации, бывает, нужно привести поток данных к жёстко фиксированному диапазону. Хорошо, если мы активно используем OpenCL: тогда есть готовая инструкция
gentype clamp(
    gentype x,
    gentype minval,
    gentype maxval)
Но никто в здравом уме не будет городить тяжеловесный OpenCL, чтобы привести int к unsigned char.

Обычно, для приведения числа к [0; 255] на CPU я пользовался таким кодом (С++):
char byteN = (intN > 255) ? 255 : (intN < 0) ? 0 : intN;

Оказывается, есть более быстрый способ. Когда-нибудь компиляторы C++ научатся лучше понимать, чего от них хотят. Ну а пока такой вот код для приведения целого числа к беззнаковому байту - самый-самый:
unsigned char clamp( int n ) {
    int a = 255;
    a -= n;
    a >>= 31;
    a |= n;
    n >>= 31;
    n = ~n;
    n &= a;
    return n;
}

Мне этот код не нравится. Но если он понравился Вам, наверняка, понравится и содержимое этой страницы >http://graphics.stanford.edu/~seander/bithacks.html
Крайне быстро. Крайне непонятно. Крайне эффективно. C++)

1 комментарий:

Анонимный комментирует...

почерпнул много нового