想象一下,我有两个无符号字节bx。我需要将bsub计算为b - xbadd作为b + x。但是,我不希望在这些操作期间发生下溢/上溢。例如(伪代码):

b = 3; x = 5;
bsub = b - x; // bsub must be 0, not 254


b = 250; x = 10;
badd = b + x; // badd must be 255, not 4

这样做的明显方法包括分支:
bsub = b - min(b, x);
badd = b + min(255 - b, x);

我只是想知道是否有更好的方法来做到这一点,即通过一些骇人听闻的操纵?

最佳答案

Branchfree Saturating Arithmetic文章为此提供了策略:

他们的附加解决方案如下:

u32b sat_addu32b(u32b x, u32b y)
{
    u32b res = x + y;
    res |= -(res < x);

    return res;
}

修改为uint8_t:
uint8_t  sat_addu8b(uint8_t x, uint8_t y)
{
    uint8_t res = x + y;
    res |= -(res < x);

    return res;
}

他们的减法解决方案是:
u32b sat_subu32b(u32b x, u32b y)
{
    u32b res = x - y;
    res &= -(res <= x);

    return res;
}

修改为uint8_t:
uint8_t sat_subu8b(uint8_t x, uint8_t y)
{
    uint8_t res = x - y;
    res &= -(res <= x);

    return res;
}

关于c++ - 饱和减/加无符号字节,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/33481295/

10-10 04:33