7
string convert_binary_to_hex(string binary_value, int number_of_bits)
{
    bitset<number_of_bits> set(binary_value);   
    ostringstream result;
    result << hex << set.to_ulong() << endl;
    return result.str();
}

在上述方法中,我将二进制字符串转换为十六进制字符串。由于十六进制值是 4 位,因此该number_of_bits变量需要是 4 的倍数,因为binary_value我正在编写的应用程序的范围可以从 4 位到 256 位不等。

如何让 bitset 采用可变大小?

我的进口:

#include <stdio.h>
#include <iostream>
#include <string>
#include <bitset>
#include <sstream>
4

6 回答 6

8

你不能。像这样的模板参数需要在编译时知道,因为编译器需要根据传递的值生成不同的代码。

在这种情况下,您可能想要迭代您的字符串并自己建立值,例如

unsigned long result = 0;
for(int i = 0; i < binary_value.length(); ++i)
{
    result <<= 1;
    if (binary_value[i] != '0') result |= 1;
}

但是,它还假设您的结果比 long 短,并且不会容纳 256 位值 - 但您的示例代码也不会。你需要一个大数字类型。

于 2011-03-17T15:44:42.350 回答
5

std::bitset的大小只能是编译时已知的常量(常量表达式),因为它是一个完整的模板参数。常量表达式包括用常量表达式初始化的整型文字和/或常量整型变量。

例如

std::bitset<4> q; //OK, 4 is a constant expression
const int x = 4;
std::bitset<x> qq; //OK, x is a constant expression, because it is const and is initialized with constant expression 4;
int y = 3;
const int z = y;
std::bitset<z> qqq; //Error, z isn't a constant expression, because even though it is const it is initialized with a non-constant expression

使用std::vector<bool>boost::dynamic_bitset此处链接)代替动态(未知编译时)大小。

于 2011-03-17T15:43:20.823 回答
3

你不 -std::bitset是一个模板,它的大小必须在编译时指定。

您需要自己制作convert_binary_to_hex模板。如果仅在运行时知道大小,则必须找到另一种解决方案。

template<size_t number_of_bits>
string convert_binary_to_hex(string binary_value)
{
   bitset<number_of_bits> set(binary_value);   
   ostringstream result;
   result << hex << set.to_ulong() << endl;
   return result.str();
}
于 2011-03-17T15:44:58.040 回答
2

据我记得你可以使用模板来解决这个问题:

template <size_t number_of_bits>
    string convert_binary_to_hex(string binary_value)
    {
        bitset<number_of_bits> set(binary_value);   
        ostringstream result;
        result << hex << set.to_ulong() << endl;
        return result.str();
    }

然后这样称呼它:

convert_binary_to_hex<32>(12345678);

请注意,您仍然只能传递常量,但现在每个调用都可以获取另一个常量:)

于 2011-03-17T15:46:50.073 回答
2

如果您可以在编译时知道大小,则也将您的方法设为模板,否则您将需要使用std::vector<bool>实际上专门用于仅使用一位的模板bool,但您必须ulong手动使用 or 和 bitshifts 构建。

//template version
template <size_t number_of_bits>
string convert_binary_to_hex(string binary_value) {
    bitset<number_of_bits> set(binary_value);
    ostringstream result;
    result << hex << set.to_ulong() << endl;
    return result.str();
} 

但是,既然您已经假设 aulong将足够大以容纳位数,并且如果您给出的代码有太多位,它不会有什么不同,为什么不把它的大小设置为一个ulong

//reuses ulong assumption
string convert_binary_to_hex(string binary_value) {
    bitset<sizeof(ulong)> set(binary_value);
    ostringstream result;
    result << hex << set.to_ulong() << endl;
    return result.str();
} 

或者你可以只有 2 个函数,一个执行 4 位数字的实际转换,另一个使用该函数来建立任意长度的数字:

string convert_nibble_to_hex(string binary_value) {
    bitset<4> set(binary_value);
    ostringstream result;
    result << hex << set.to_ulong() << endl;
    return result.str();
}

string convert_binary_to_hex(string binary_value) {
    //call convert_nibble_to_hex binary_value.length()/4 times
    //and concatenate results
}
于 2011-03-17T15:46:02.160 回答
1

您可以使用一个 8 位字符始终需要两个十六进制数字这一事实。不需要同时将整个字符串变成位序列,可以对字符串元素进行单独处理。

string convert_octets_to_hex(string value)
{
    string result(2*value.size());
    for( int i = 0; i < value.size(); i++ ) {
        result[2*i]   = "0123456789abcdef"[(value[i] >> 4) & 0x0f];
        result[2*i+1] = "0123456789abcdef"[value[i] & 0x0f];
    }
    return result;
}

哦,我看到你有一个 1 位的字符串。可以用同样的方式处理:

string convert_binary_to_hex(string binary_value, int number_of_bits = -1)
{
    if (number_of_bits < 0) number_of_bits = binary_value.size();
    string result((number_of_bits + 3) / 4, '\0');

    unsigned work;
    char* in = &binary_value[0];
    char* out = &result[0];
    if (number_of_bits & 3) {
        work = 0;
        while (number_of_bits & 3) {
            work <<= 1;
            work |= *(in++) & 1;
            number_of_bits--;
        }
        *(out++) = "0123456789abcdef"[work];
    }
    while (number_of_bits) {
        work = ((in[0] & 1) << 3) | ((in[1] & 1) << 2) | ((in[2] & 1) << 1) | (in[3] & 1);
        in += 4;
        *(out++) = "0123456789abcdef"[work];
        number_of_bits -= 4;
    }
    return result;
}

编辑:修复了一些错误,添加了一个演示

于 2011-03-17T15:48:13.827 回答