Как обернуть число с помощью оператора мод - PullRequest
3 голосов
/ 28 января 2011

Не уверен, если это возможно, но есть ли автоматический способ, использующий мод или что-то подобное, для автоматической коррекции неверных входных значений? Например:

If r>255, then set r=255 and
if r<0, then set r=0

Итак, в основном я спрашиваю, какой умный математический способ установить это вместо использования

if(r>255)
 r=255;
if(r<0)
 r=0;

Ответы [ 5 ]

7 голосов
/ 28 января 2011

Как насчет:

r = std:max(0, std::min(r, 255));
2 голосов
/ 28 января 2011

Следующая функция выведет то, что вы ищете:

 f(x) = (510*(1 + Sign[-255 + x]) + x*(1 + Sign[255 - x])*(1 + Sign[x]))/4

Как показано здесь:

enter image description here

0 голосов
/ 28 января 2011

У меня была похожая проблема при работе с изображениями. Для некоторых специальных значений (например, 0 и 255) вы можете использовать этот непереносимый метод:

static inline int trim_8bit(unsigned i){
    return 0xff & ((i | -!!(i & ~0xff))) + (i >> 31);
    // where "0xff &" can be omitted if you return unsigned char
};

В реальных случаях зажимание должно выполняться редко, чтобы вы могли написать

static inline unsigned char trim_8bit_v2(unsigned i){   
    if (__builtin_expect(i & ~0xFF, 0)) // it's for gcc, use __assume for MSVC
        return (i >> 31) - 1; 
    return i;
};

И чтобы быть уверенным, что быстрее, измерьте.

0 голосов
/ 28 января 2011

В зависимости от того, как ваше оборудование и, возможно, как ваш интерпретатор работает с целыми числами, вы можете сделать это:

Предполагая, что беззнаковое целое число равно 16 битам (чтобы мои маски были короткими):

r = r & 0000000011111111;

Если бы int был 32-битным, вам понадобилось бы еще 16 нулей в начале битовой маски.

После этого побитового AND максимальное значение r может быть равно 255. В зависимости от аппаратного обеспечения,беззнаковое целое может сделать что-то странное, если значение меньше нуля.Я считаю, что этот случай уже обрабатывается битовой маской (по крайней мере, на оборудовании, которое я использовал).Если нет, вы можете сначала сделать r = min(r, 0);.

0 голосов
/ 28 января 2011

Не могли бы вы сделать что-то вроде -

R = MIN(r, 255);
R = MAX(R, 0);
...