2014-09-02 50 views
2

標準(或提升)是否提供了一種增加整數的方法,以確保它不會延續並從零開始,但將值保持在最大值?或者我只需要創建自己的(這確實看起來像應該包含的一個小實用程序功能)。鉗位遞增整數?

template<typename T> 
void Increment(T& x) 
{ 
    if(x != std::numeric_limits<T>::max()) ++x; 
} 
+6

這將是一個飽和增量。一個安全的增量會表明結果溢出。 – 2014-09-02 03:48:36

+2

據我所知,在C++標準或boost中沒有這樣的東西。 – 2014-09-02 04:03:32

+2

http://stackoverflow.com/questions/121240/saturating-addition-in-c – 2014-09-02 04:46:51

回答

2

據我所知,沒有這樣的工具,所以你需要建立你自己的。

有一篇很好的文章,涵蓋了飽和算術:Branchfree Saturating Arithmetic,它們涵蓋了所有的算術運算。他們的例子是C語言,但不應該很難翻譯。

對於你的情況,我們會在尋找另外。他們假定:

#include <limits.h> 

typedef unsigned u32b; 

typedef signed s32b; 

和無符號此外,他們還提供了下面的代碼:

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

    return res; 
} 

和符號相加:

s32b sat_adds32b(s32b x, s32b y) 
{ 
    u32b ux = x; 
    u32b uy = y; 
    u32b res = ux + uy; 

    /* Calculate overflowed result. (Don't change the sign bit of ux) */ 
    ux = (ux >> 31) + INT_MAX; 

    /* Force compiler to use cmovns instruction */ 
    if ((s32b) ((ux^uy) | ~(uy^res)) >= 0) 
    { 
     res = ux; 
    } 

    return res; 
} 

帕斯卡Cuoq在無符號評論指出案例假定兩個補碼對絕大多數案件都應該是正確的,但是該標準沒有對基礎代表做出假設。

+0

你的意思是簽署的案例假設是補碼?未簽名的情況假定爲模塊化算術,標準規定爲unsigned int,儘管不一定適用於較小的無符號類型(即使對於那些,增加通常也是安全的,但是在討厭的實現中,即使遞增未簽名的short也可能產生未定義行爲,即使它具有與unsigned int相同的範圍 – supercat 2015-11-03 00:34:36

+0

@supercat你知道我不確定,看起來他正在推銷爲簽名類型,但似乎並不是這種情況 – 2015-11-03 01:12:54

+0

從較小的一箇中減去一個較大的無符號值(UINT_MAX + 1)減去差值。 – supercat 2015-11-03 02:37:27