C/C++ 两个宏的幂
C/C++ power of two macro
我的二次幂没有达到应有的水平,所以我想也许我可以 #define
做点什么。
不幸的是,我在预处理器指令方面经验不足,我不知道如何做 for 循环之类的事情。我看了:
- http://www.cplusplus.com/doc/tutorial/preprocessor
- https://msdn.microsoft.com/en-us/library/teas0593.aspx
但是他们都没有for循环的例子。我想要的只是能够写出类似 pwrtwo(5)
的东西,而不是使用计算器来计算 25 是 32.
2x 是 1 << 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;
}
我的二次幂没有达到应有的水平,所以我想也许我可以 #define
做点什么。
不幸的是,我在预处理器指令方面经验不足,我不知道如何做 for 循环之类的事情。我看了:
- http://www.cplusplus.com/doc/tutorial/preprocessor
- https://msdn.microsoft.com/en-us/library/teas0593.aspx
但是他们都没有for循环的例子。我想要的只是能够写出类似 pwrtwo(5)
的东西,而不是使用计算器来计算 25 是 32.
2x 是 1 << 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;
}