将二进制数转换为十进制数的快速方法

时间:2012-06-08 13:09:26

标签: c++ binary

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

5 个答案:

答案 0 :(得分:10)

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

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;
}

答案 1 :(得分:7)

好吧,如果这个“数字”实际上是从某个来源(从文件或用户读取)获得的字符串,你转换成一个数字(认为它更适合实际数字),这是相当的可能,您可以使用std::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)但这可能不再是最有效的方式,因为其他人已经提出了基于数字的更有效的算法。但正如所说,我怀疑你真的把这个数字作为一个实际的整数变量,而不是从一些文本文件或用户那里读取它。

答案 2 :(得分:3)

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

如果你想在你的源代码中编写一个二进制文件,你应该使用BOOST_BINARY。然后你需要使用cout打印它,十进制是默认值...

unsigned int i = BOOST_BINARY(10101010);
std::cout << i; // This prints 170

答案 3 :(得分: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

答案 4 :(得分: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(因此不能验证它实际上是二进制输入。)< / p>

当然,它非常具体而且不够灵活,但是它可以完成工作而我不确定你会得到更快的速度。