12

我必须尽快将二进制数转换为unsigned int bin_number = 10101010十进制表示(即170)?什么是最好的算法?

4

5 回答 5

14

使用模板可以在编译时解决这个问题。

template<unsigned long num>
struct binary
{
    static unsigned const value =
        binary<num/10>::value << 1 | num % 10;
};

// Specialization for zero
template<>
struct binary<0>
{ static unsigned const value = 0; };

二进制模板再次用较小的 实例化num,直到num达到零,并将特化用作终止条件。

例子:std::cout << binary<10101010>::value;

对于运行时问题:

unsigned binary_to_decimal(unsigned num)
{
    unsigned res = 0;

    for(int i = 0; num > 0; ++i)
    {
        if((num % 10) == 1)
            res += (1 << i);

        num /= 10;
    }

    return res;
}
于 2012-06-08T13:10:58.493 回答
11

好吧,如果这个“数字”实际上是从某个源(从文件或用户读取)获得的字符串,您将其转换为数字(认为它更适合实际数字),这很可能,您可以使用 astd::bitset进行转换:

#include <bitset>

unsigned int number = std::bitset<32>("10101010").to_ulong();

(当然32这里是实现定义的,可能更合适地写为std::numeric_limits<unsigned int>::digits。)

但是,如果它确实是(非常)第一位的数字(整数变量),您可以这样做:

#include <string>

unsigned int number = std::bitset<32>(std::to_string(bin_number)).to_ulong();

(使用 C++11 的to_string)但这可能不再是最有效的方法,因为其他人已经提出了基于数字的更有效的算法。但如前所述,我怀疑你是否真的把这个数字作为一个实际的整数变量放在首位,而是从某个文本文件或用户那里读取它。

于 2012-06-08T13:49:33.853 回答
4

实际上,如果您编写unsigned int bin_number = 10101010,编译器会将其解释为十进制数。

如果要在源代码中编写二进制文字,则应使用BOOST_BINARY. 然后,您只需要使用 打印它cout,十进制是默认值...

unsigned int i = BOOST_BINARY(10101010);
std::cout << i; // This prints 170
于 2012-06-08T13:19:37.920 回答
1

由于 C++11(即使 C++11 在这方面比 C++14 更受限制),函数constexpr可以避免template具有编译时值的必要性。

这里是兼容 C++14 的版本:

constexpr unsigned binary_to_decimal(unsigned num)
{
    unsigned res = 0;

    while (num)
    {
        res = 10 * res + num % 10;
        num /= 10;
    }
    return res;
}

对于文字,您甚至可以使用 C++14 以来的二进制文字:

0b1010'1010 // or 0b10101010 without separator
于 2019-06-13T21:40:39.173 回答
0

如果您知道您正在处理的二进制数字的数量并且它始终是固定的并且二进制数字在运行时以字符串形式出现(就像从文件或标准输入中读取一样)(即编译时转换不可能)那么你可以采用这种方法:

int to_binary( const char* c )
{
    return ( ( c[0] & 1 ) ? 0x80 : 0x00 ) |
           ( ( c[1] & 1 ) ? 0x40 : 0x00 ) |
           ( ( c[2] & 1 ) ? 0x20 : 0x00 ) |
           ( ( c[3] & 1 ) ? 0x10 : 0x00 ) |
           ( ( c[4] & 1 ) ? 0x08 : 0x00 ) |
           ( ( c[5] & 1 ) ? 0x04 : 0x00 ) |
           ( ( c[6] & 1 ) ? 0x02 : 0x00 ) |
           ( ( c[7] & 1 ) ? 0x01 : 0x00 );
}

这假定一个固定的八位二进制数。像这样调用:

std::cout << to_binary("10101010") << std::endl;

如果您有一个 16 位数字,您仍然可以使用它:

const char* bin_number = "1010101010101010";

// Deal with 16 bits
std::cout << ( to_binary( bin_number ) << 8 | to_binary( bin_number + 8 ) ) << std::endl;

请注意,这里显然没有边界检查,我依赖于“1”的 LSB 始终为 1 而“0”始终为 0(因此不验证它实际上是二进制输入。)

自然,它非常具体且不是很灵活,但它确实可以完成工作,我不确定你会变得更快。

于 2012-06-08T13:57:39.213 回答