C/C++ 两个宏的幂

C/C++ power of two macro

我的二次幂没有达到应有的水平,所以我想也许我可以 #define 做点什么。

不幸的是,我在预处理器指令方面经验不足,我不知道如何做 for 循环之类的事情。我看了:

但是他们都没有for循环的例子。我想要的只是能够写出类似 pwrtwo(5) 的东西,而不是使用计算器来计算 25 是 32.

2x1 << x,所以:

#define pwrtwo(x) (1 << (x))

为什么不正确地使用一个函数呢?这甚至允许我们使用强大的 constexpr 在编译时生成结果!

template <class T>
constexpr T pwrtwo(T exponent) {
    return (T(1) << exponent);
}

一个答案(错误地)建议答案应该是 #define pwrtwo(x) (1 << ((x) - 1)。然而:

1 = 0000 0001 二进制模式

现在,当要求 2 的 5 次方时,

1 << (5-1) ;其中 x = 5

1 应该移动 4 次,然后结果将是

0001 0000 ==> 2 的幂 4

但这是错误的,这就是为什么实际答案应该是:

#define pwrtwo(x) (1 << (x))

这个宏将完成这项工作:

#ifndef PWRTWO
#define PWRTWO(EXP) (1 << (EXP))
#endif

但是,建议不要使用它,除非您限制或限制 EXP 可以达到的值范围!

尝试在 int 的大小为 4 个字节的机器上将这些值一次一个地输入到此宏中,尝试编译并 运行,然后告诉我发生了什么每个值:

std::cout << PWRTWO(30) << std::endl; // Okay
std::cout << PWRTWO(31) << std::endl; // - value

// In the following cout statement within the macro, do not confuse the 
// (x >= 32) as what is actually being passed into the macro as an argument. 
// This is just a short hand notation to represent all values >= 32 where the actual
// numerical value would be entered into this macro statement as there is
// no defined variable x here in this context nor any comparison expression being passed to it.

// Compiler Warning C4293 '<<' shift count negative or two big, undefined behavoir
std::cout << PWRTWO(X >= 32) << std::endl; // In most cases on my machine it prints out 0. 
//However, since this is undefined behavior, there is no telling what it could or may do on another machine.

编辑

// Try this for loop to see the actual values being printed out as long as 
// the integer value on your machine is 32bit or 4 bytes in size.
std::cout << "Excepted values for 32bit integers" << std::endl;
std::cout << "----------------------------------\n";
for ( int i = 0; i < 31; i++ ) {
    std::cout << PWRTWO( i ) << std::endl;
}
std::cout << std::endl;

// Then print out the next one
std::cout << "First value to produce a negative result with int being 32bit." << std::endl;
std::cout << "------------------------------------------\n";
std::cout << PWRTWO( 31 ) << std::endl << std::endl;

// Then print out these as well : compiler warnings
std::cout << "Value Range that generates a compiler error." << std::endl;
std::cout << "-------------------------------------------\n";
for ( int i = 32; i <= 100; i++ ) {
    std::cout << PWRTWO( i ) << std::endl;
}