首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >无符号字节的饱和减法/加法

无符号字节的饱和减法/加法
EN

Stack Overflow用户
提问于 2015-11-02 23:35:53
回答 9查看 13.4K关注 0票数 85

假设我有两个无符号字节bx。我需要将bsub计算为b - x,将badd计算为b + x。但是,我不希望在这些操作过程中发生下溢/溢出。例如(伪代码):

代码语言:javascript
复制
b = 3; x = 5;
bsub = b - x; // bsub must be 0, not 254

代码语言:javascript
复制
b = 250; x = 10;
badd = b + x; // badd must be 255, not 4

最明显的方法包括分支:

代码语言:javascript
复制
bsub = b - min(b, x);
badd = b + min(255 - b, x);

我只是想知道是否有更好的方法来做到这一点,即通过一些老生常谈的比特操作?

EN

回答 9

Stack Overflow用户

回答已采纳

发布于 2015-11-03 00:17:37

文章Branchfree Saturating Arithmetic提供了实现这一点的策略:

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

代码语言:javascript
复制
u32b sat_addu32b(u32b x, u32b y)
{
    u32b res = x + y;
    res |= -(res < x);

    return res;
}

针对uint8_t进行了修改:

代码语言:javascript
复制
uint8_t  sat_addu8b(uint8_t x, uint8_t y)
{
    uint8_t res = x + y;
    res |= -(res < x);

    return res;
}

他们的减法解决方案是:

代码语言:javascript
复制
u32b sat_subu32b(u32b x, u32b y)
{
    u32b res = x - y;
    res &= -(res <= x);

    return res;
}

针对uint8_t进行了修改:

代码语言:javascript
复制
uint8_t sat_subu8b(uint8_t x, uint8_t y)
{
    uint8_t res = x - y;
    res &= -(res <= x);

    return res;
}
票数 87
EN

Stack Overflow用户

发布于 2015-11-02 23:50:29

一种简单的方法是检测溢出并相应地重置该值,如下所示

代码语言:javascript
复制
bsub = b - x;
if (bsub > b)
{
    bsub = 0;
}

badd = b + x;
if (badd < b)
{
    badd = 255;
}

在使用-O2编译时,GCC可以将溢出检查优化为条件赋值。

我测量了与其他解决方案相比的优化程度。在我的PC上进行1000000000+操作时,这个解决方案和@ShafikYaghmour的平均时间为4.2秒,而@chux的平均时间为4.8秒。这种解决方案也更具可读性。

票数 40
EN

Stack Overflow用户

发布于 2015-11-03 14:40:19

如果您使用的是足够新的版本,那么您可以使用built-ins来检测溢出。

代码语言:javascript
复制
if (__builtin_add_overflow(a,b,&c))
{
  c = UINT_MAX;
}
票数 13
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33481295

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档