想象一下,我有两个无符号字节b
和x
。我需要将bsub
计算为b - x
和badd
作为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/