繁体   English   中英

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

[英]Fast way to convert a binary number to a decimal number

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

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

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

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

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

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

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

从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

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

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(因此不能验证它实际上是二进制输入。)

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM