位掩码取决于数据类型
Bitmask depending on data type
我想应用位掩码以仅获取上半位。所以对于 uint32 它将是这样的:
uint32_t version_part = oldID & 0xFFFF0000;
当数据类型被硬编码时这一切都很好,但如果这是一个模板化函数并且我想提供一个任意数据类型(uint8_t、uint16_t、...)我想要按比例调整位掩码的大小(0xF0、0xFF00、...),最好在编译时调整。
考虑到数据类型的数量是有限的,我想你可以做 if-cases(静态 if's?),但我想知道是否有更好的方法来做到这一点。
下面的内容是否解决了您的目的?
template<typename T>
T maskbits(T oldID)
{
const size_t SZ = sizeof oldID * CHAR_BIT;
const T mask = (static_cast<T>((1ULL << (SZ / 2)) - 1ULL)) << (SZ / 2);
return oldID & mask;
}
Mohit Jain 的回答很好。但是由于您使用的是模板,您还可以使用模板专业化来做一些事情:
/* general case */
template<typename T> class Mask { };
/* specific cases */
template<> class Mask<uint16_t> {public: static const uint16_t value = 0xFF00; };
template<> class Mask<uint32_t> {public: static const uint32_t value = 0xFFFF0000; };
/* etc. */
template<typename T>
constexpr T maskbits(T uid)
{
return uid & Mask<T>::value;
}
最大的好处是您可以将一般情况留空,以便在不受支持的类型上出现编译错误。当然你也可以让那个计算掩码,这取决于你的需要。
也许你可以试试这个,它适用于任何整数大小。
#include <iostream>
template<typename T>
T mask(T a = 0) {
return (~T(0)) << 4*sizeof(T);
}
int main()
{
unsigned char v = mask<unsigned char>();
int v2 = mask(32);
std::cout << "v = 0x" << std::hex << (unsigned int)v << std::endl;
std::cout << "v2 = 0x" << std::hex << (unsigned int)v2 << std::endl;
}
输出为:
v = 0xf0
v2 = 0xffff0000
编辑:我刚刚检查并启用了优化,编译器可以在编译时生成掩码
我想应用位掩码以仅获取上半位。所以对于 uint32 它将是这样的:
uint32_t version_part = oldID & 0xFFFF0000;
当数据类型被硬编码时这一切都很好,但如果这是一个模板化函数并且我想提供一个任意数据类型(uint8_t、uint16_t、...)我想要按比例调整位掩码的大小(0xF0、0xFF00、...),最好在编译时调整。
考虑到数据类型的数量是有限的,我想你可以做 if-cases(静态 if's?),但我想知道是否有更好的方法来做到这一点。
下面的内容是否解决了您的目的?
template<typename T>
T maskbits(T oldID)
{
const size_t SZ = sizeof oldID * CHAR_BIT;
const T mask = (static_cast<T>((1ULL << (SZ / 2)) - 1ULL)) << (SZ / 2);
return oldID & mask;
}
Mohit Jain 的回答很好。但是由于您使用的是模板,您还可以使用模板专业化来做一些事情:
/* general case */
template<typename T> class Mask { };
/* specific cases */
template<> class Mask<uint16_t> {public: static const uint16_t value = 0xFF00; };
template<> class Mask<uint32_t> {public: static const uint32_t value = 0xFFFF0000; };
/* etc. */
template<typename T>
constexpr T maskbits(T uid)
{
return uid & Mask<T>::value;
}
最大的好处是您可以将一般情况留空,以便在不受支持的类型上出现编译错误。当然你也可以让那个计算掩码,这取决于你的需要。
也许你可以试试这个,它适用于任何整数大小。
#include <iostream>
template<typename T>
T mask(T a = 0) {
return (~T(0)) << 4*sizeof(T);
}
int main()
{
unsigned char v = mask<unsigned char>();
int v2 = mask(32);
std::cout << "v = 0x" << std::hex << (unsigned int)v << std::endl;
std::cout << "v2 = 0x" << std::hex << (unsigned int)v2 << std::endl;
}
输出为:
v = 0xf0
v2 = 0xffff0000
编辑:我刚刚检查并启用了优化,编译器可以在编译时生成掩码