【问题标题】:Clamped Increment Integer?钳位增量整数?
【发布时间】:2014-10-26 05:59:12
【问题描述】:

标准(或提升)是否提供了一种递增整数的方法,以确保它不会结转并从零开始,但将值保持在最大值?还是我只需要创建我自己的(这看起来确实是一个应该包含的小实用功能)。

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

【问题讨论】:

标签: c++ boost


【解决方案1】:

据我所知,没有这样的实用程序,所以您需要自己构建。

有一篇很好的文章涵盖了饱和算术: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;
}

正如 Pascal Cuoq 在评论中指出的那样,未签名的情况假设二进制补码,这对于绝大多数情况应该没问题,但标准并未对基础表示进行假设。

【讨论】:

  • 你的意思是签名的情况下假设二进制补码?无符号情况假定模块化算法,标准要求无符号整数,但不一定适用于较小的无符号类型(即使对于那些,加法通常也是安全的,但在一个讨厌的实现中,即使增加一个无符号的短也可能产生未定义的行为,即使它有与 unsigned int 范围相同。
  • @supercat 你知道我不确定,看起来他正在假设晋升为签名类型,但情况似乎不应该如此。
  • 从较小的值中减去较大的无符号值,得到 (UINT_MAX+1) 减去差值。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-10-31
  • 1970-01-01
  • 1970-01-01
  • 2015-07-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多