饱和减/加无符号字节 [英] Saturating subtract/add for unsigned bytes

查看:213
本文介绍了饱和减/加无符号字节的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Imagine I have two unsigned bytes b and x. I need to calculate bsub as b - x and badd as b + x. However, I don't want underflow/overflow occur during these operations. For example (pseudo-code):

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

执行此操作的明显方法包括分支:

The obvious way to do this includes branching:

bsub = b - min(b, x);
badd = b + min(255 - b, x);

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

I just wonder if there are any better ways to do this, i.e. by some hacky bit manipulations?

推荐答案

文章无分支饱和算法为此提供了策略:

The article Branchfree Saturating Arithmetic provides strategies for this:

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

Their addition solution is as follows:

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

    return res;
}

针对uint8_t进行了修改:

modified for 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进行了修改:

modified for uint8_t:

uint8_t sat_subu8b(uint8_t x, uint8_t y)
{
    uint8_t res = x - y;
    res &= -(res <= x);

    return res;
}

这篇关于饱和减/加无符号字节的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆