获取许多内置类型的低部分

时间:2018-05-18 19:44:46

标签: c++

如何创建一个返回N位数低位的函数模板? 例如,对于8位数字,得到最低有效4位,对于16位数字,得到最低有效8位。

2 个答案:

答案 0 :(得分:3)

要获得内置整数类型的下半部分,您可以尝试这样的事情:

#include <iostream>
#include <climits>

using std::cout;
using std::endl;

template<typename T>
constexpr T lowbits(T v) {
    return v & (T(1) << CHAR_BIT * sizeof v / 2) - 1;
}

int main() {
    cout << std::hex << (int)lowbits<int8_t>(0xde) << endl; // will print e
    cout << std::hex << lowbits<int16_t>(0xdead) << endl; // will print ad
    cout << std::hex << lowbits<int32_t>(0xdeadbeef) << endl; // will print beef
    cout << std::hex << lowbits<int64_t>(0xbeefdeaddeadbeef) << endl; // will print deadbeef
}

请注意

return v & (T(1) << CHAR_BIT * sizeof v / 2) - 1;

相当于:

return v & (
             (static_cast<T>(1) 
             <<
             (CHAR_BIT * (sizeof v) / 2)) // number of bits divided by 2
             - 1
            );

本质上,您创建的是一个位掩码(简单的另一个整数),所有高位都有0位,所有低位都有1位。

如果整数类型具有N位,则通过将1位移入N位置然后从中减去1来完成此操作。减法的结果是1以下的所有位都将被设置。

使用给定的值,只产生值v的下半部分。

您可以通过将CHAR_BIT * sizeof v/2替换为要检索的位数来轻松概括此方法以检索任意数量的低位。

要获得更高的位,您可以使用~运算符简单地否定生成的掩码。

如果您需要任意大小的整数,可以尝试在GNU gmp library中找到此过程的等效操作。

答案 1 :(得分:1)

让我们定义一个名为mask的变量,它是掩盖(或保留)某些位的模式。获得最低有效位的操作是:
result = value & mask;

例如,使用value == 13和mask == 7进行测试。

这适用于所有POD类型,浮点除外。浮点的最低有效Q位没有意义(除非你真的需要这样做)。

如果您不需要比最大内部积分类型更多的位,您可以使用以下内容:

template <typename T>
T low_bits(T data, size_t bit_count)
{
  T mask = (1U << bit_count) - 1U;
  return value & mask;
}

对于非模板解决方案,可以使用宏:

#define LOW_BITS(value, bit_count) \
    (value & ((1U << bit_count) - 1U))

这使编译器可以根据value的数据类型找出代码 表达式的宏形式:value & mask

N > sizeof(*largest type*)时,刺或问题开始发挥作用。在这种情况下,数字不能由内部数据类型表示,因此必须提出不同的解决方案。

N - 位的解决方案取决于数字的多字节表示是Big Endian还是Little Endian。对于Big Endian平台,最低有效值将位于最高地址,而在Little Endian平台上,最低有效值位于最低地址。

我建议的解决方案将N-bit数字视为字节数组。一个字节包含8位(在大多数平台上),字节的掩码可能与多字节数不同。

这是算法: 1.将完全屏蔽的最低有效字节复制到结果变量 2.屏蔽下一个最大字节并将结果字节复制到结果编号 3.用0填充剩余字节。

就功能参数而言,您需要:
1)指向原始号码的存储位置 2)指向结果编号的指针 3)指向面具的指针 4)数字的大小,以字节为单位。

该算法可以处理N-bit个数字,受平台内存量的限制。

注意:抱歉不提供代码,但我需要重新开始工作。 : - (