C++ 位旋转:使用c+中的模板查找二的下一次幂+;

C++ 位旋转:使用c+中的模板查找二的下一次幂+;,c++,templates,bit-manipulation,C++,Templates,Bit Manipulation,这是我一般性问题的后续行动: 我现在创建了以下模板函数: template <typename T> T nextPowerOfTwo(T n) { std::size_t k=1; n--; do { n |= n >> k ; k <<=1; } while (k < sizeof(T)*8) return ++n; } 模板 T下一个动力2(T n) { 标准:尺寸

这是我一般性问题的后续行动:

我现在创建了以下模板函数:

template <typename T>
T nextPowerOfTwo(T n)
{
    std::size_t k=1;
    n--;
    do {
        n |= n >> k ;
        k <<=1;
    }
    while (k < sizeof(T)*8)
    return ++n;
}
模板
T下一个动力2(T n)
{
标准:尺寸k=1;
n--;
做{
n |=n>>k;
k
模板
下一个动力二(T v)
{
如果(v<1)返回0;
--五,;
对于(int i=0;i>(1
模板
下一个动力二(T v)
{
如果(v<1)返回0;
--五,;
对于(int i=0;iv |=v>>(1如果你希望你的函数是泛型的,这是你明确想要的,你也希望能够使用用户定义的类型,它不会有关键字
unsigned
。相反,你应该使用
std::numeric\u limits
来测试是否有符号(或者,在这种情况下,没有符号)


您也不应使用
8*sizeof(T)
,而应使用
数值限制来确定您的类型有多少位。:-)

如果你想让你的函数成为泛型函数(你显然想这样做),那么你也希望能够使用用户定义的类型,而不是关键字
unsigned
。相反,你应该使用
std::numeric\u limits
来测试是否有符号(或者在这种情况下,没有符号)


您也不应使用
8*sizeof(T)
,而应使用
数值限制来确定您的类型有多少位。:-)

要回答第一个问题,不可以。T必须可以使用完整的类型声明进行重放;将unsigned放在T之前可能会导致unsigned unsigned int或类似的结果


这并不完全是秘密发生的事情,但它很好地解释了为什么不能使用unsigned。

要回答您的第一个问题,不,您不能。t必须可以用完整的类型声明进行重放;将unsigned放在t之前可能会导致unsigned unsigned int或类似的结果

template<typename T>
T nextPowerOfTwo(T n) {
    --n;
    for(T k=1;!(k&(1<<(sizeof(n)+1));k<<=1) n|=n>>k;
    return ++n;
}
这并不完全是发生在封面下的事情,但它很好地解释了为什么不能使用unsigned。

template
template<typename T>
T nextPowerOfTwo(T n) {
    --n;
    for(T k=1;!(k&(1<<(sizeof(n)+1));k<<=1) n|=n>>k;
    return ++n;
}
T下一个动力2(T n){ --n; 对于(tk=1;!(k&(1
template
T下一个动力2(T n){
--n;

对于(tk=1;!(k&(1您可以通过更改循环测试来检查数字是否比2的幂小1来稍微改进:

template <typename T>
T nextPowerOfTwo(T n)
{
    std::size_t k=1;
    --n;
    do {
        n |= n >> k;
        k <<= 1;
    } while (n & (n + 1));
    return n + 1;
}
模板
T下一个动力2(T n)
{
标准:尺寸k=1;
--n;
做{
n |=n>>k;

k您可以通过更改循环测试来检查数字是否比2的幂小1,从而稍微改善情况:

template <typename T>
T nextPowerOfTwo(T n)
{
    std::size_t k=1;
    --n;
    do {
        n |= n >> k;
        k <<= 1;
    } while (n & (n + 1));
    return n + 1;
}
模板
T下一个动力2(T n)
{
标准:尺寸k=1;
--n;
做{
n |=n>>k;

k虽然@hacker的版本在技术上是正确的,但我的Visual Studio 2008未能对其进行适当优化。这是我的版本,它工作得非常完美。它还可以根据您的请求执行对数数量的操作。虽然这个版本没有那么优雅,但Visual Studio实际上能够计算出最接近两个的
的值(value)
而不执行它。(当然,您必须启用优化)

模板
结构值持有者
{
静态常数T值=v;
};
模板
结构详细信息
{
typedef typename ln_detail 1)>,value_holder>::type;
};
模板
结构详细信息
{
typedef部分结果类型;
};
模板
结构层
{
静态常量T value=ln\u detail::type::value;
};
模板
T最接近的二次幂(tV)
{
如果(v<1)返回0;
--五,;
对于(int i=0;iv |=v>>(1虽然@hacker的版本在技术上是正确的,但我的Visual Studio 2008未能对其进行适当优化。这是我的版本,它工作得非常完美。它还可以根据您的请求执行对数数量的操作。尽管这个版本没有那么优雅,但Visual Studio实际上能够计算出最接近两个的
的值(value)
而不执行它。(当然,您必须启用优化)

模板
结构值持有者
{
静态常数T值=v;
};
模板
结构详细信息
{
typedef typename ln_detail 1)>,value_holder>::type;
};
模板
结构详细信息
{
typedef部分结果类型;
};
模板
结构层
{
静态常量T value=ln\u detail::type::value;
};
模板
T最接近的二次幂(tV)
{
如果(v<1)返回0;
--五,;
对于(int i=0;iv |=v>>(1hah,thx。我移位的位数当然不相关。(至少在大多数架构上)不,我很抱歉。这不起作用。它必须移位5次时会移位4次。我的示例也是垃圾。这使得几乎所有答案都是假的。我很抱歉。哈,thx。我移位的位数当然不相关。(至少在大多数架构上)不,我很抱歉。这不起作用。它在必须做5个轮班的时候会做4个轮班。我的示例也是垃圾。这使得几乎所有的答案都是假的。我很抱歉。我尝试在上面模板化的解决方案之所以如此好的部分原因是,我只需要ld(nbits)迭代,而不是nbits迭代。请参阅原始解决方案的链接。这样我就不能“过火”地抛出k.我知道我在发布错误代码时把事情搞砸了。再次抱歉。阿瓦卡,是的,我只是在改进解决方案。由于第一个问题的答案是否定的,我们对此无能为力。安德烈斯特,你是对的,我一直在编写你的代码,没有考虑太多。我已经更改了代码。部分原因是我试图将解决方案模板化为above非常好,我只需要ld(nbits)迭代,而不是nbits迭代。请参阅原始解决方案的链接。这样我就不能“过火”地抛出k.我知道我在发布错误代码时把事情搞砸了。再次抱歉。阿瓦卡,是的,我只是在改进解决方案。由于第一个问题的答案是否定的,我们对此无能为力。安德烈斯特,你是对的,我一直在编写你的代码,没有考虑太多。我更改了代码。嗯,随机的,但你不知道