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

C++ 将二进制数转换为十进制数的快速方法,c++,binary,C++,Binary,我必须尽快将二进制数(例如unsigned int bin_number=10101010)转换为十进制表示形式(即170)?最佳算法是什么?使用模板可以在编译时解决此问题 实际上,如果您写入unsigned int bin_number=10101010,编译器会将其解释为十进制数 如果要在源代码中编写二进制文字,应该使用。然后,您只需要使用cout打印它,十进制是默认值 unsigned int i = BOOST_BINARY(10101010); std::cout << i

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

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


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

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

unsigned int i = BOOST_BINARY(10101010);
std::cout << i; // This prints 170
无符号整数i=BOOST_二进制(10101010);
std::cout好的,如果这个“数字”实际上是从某个来源(从文件或用户处读取)获取的字符串,您将其转换为一个数字(认为它更适合于实际数字),这很有可能,您可以使用
std::bitset
进行转换:

#include <bitset>

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

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

如果你知道你正在处理的二进制数字的数量,并且它总是固定的,并且二进制数字以字符串的形式出现(就像从文件或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;
std::cout由于C++11(即使C++11在这方面比C++14更有限),函数可以是
constepr
,因此避免了
模板
具有编译时值的必要性

以下是与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

使用模板,您可以在编译时计算任何内容,因为它们是图灵完成的。但是这有助于OP完成任何事情吗?-1:我怀疑。如果OP有一个ICE,这是他使用元编程所需要的,他可以只做
constdouble d=170.0因为他确实在运行时得到了入站号码,所以元编程已经过时了。事实上,我认为这相当聪明,而且更重要的是,它确实有效。是的,它不会对运行时才知道的数字起作用。是的,OP很可能想要那个数字,但他没有指定。@gliderkite:Yep.)对元编程的详细阐述对那些不了解元编程的人来说是有教育意义的,如果不太可能适用于实际问题的话。更重要的是,您提供了实际问题的解决方案。虽然我不知道它是否是最快的算法,但它肯定足够快,OP也没有具体说明“最佳”是什么意思。我已经删除了我的否决票,并给了你+1。在编译时,你不需要模板,你只需要写
inti=0b10101010这是标准的:一些编译器也支持“0b”前缀(
i=0b10101010
),但使用boost可以确保可移植性。@Nick我相信这是一个在预处理过程中处理二进制文件的宏。我实际上并没有看内部结构。下面是这个特定宏的文档:如果使用正确,则不会,我完全信任boost库(说真的,如果从未使用过它们,您应该看看!)@Nick Yes和no。在这种情况下,已经采取了必要的预防措施:使用前缀以避免名称冲突,并且全部使用大写字母,这样您就知道它是一个宏,并且可以采取适当的预防措施。
10101010
是来自您程序的用户,还是只是代码中的文字?您能更好地描述二进制数的来源吗?它是在编译时知道的还是只在运行时知道的?它存储在字符串或其他结构中吗?知道了这一点,回答这个问题就容易多了。是的,我很抱歉。通常我在运行时得到数字,但有时在编译时得到。我还在学习。谢谢,这是一个很好的答案,但是数字不是字符串,我不能使用C++11,我要求一个快速的解决方案@尼克,我想问一下你是从哪里得到的,很明显你必须从某个地方得到它,我怀疑你是否真的读到了一个二进制数,它表示一个只包含0和1的数字,那将是垃圾。首先,从某种文本媒介获取这样一个数字才有意义。唯一的例外是当您需要二进制常量时,但为此您可以使用另一种方法(gliderkite的模板程序非常好)。但在大多数情况下,当它以字符串形式出现时,位集解决方案不应该是最慢的(而且也不需要C++11)。
std::cout << to_binary("10101010") << std::endl;
const char* bin_number = "1010101010101010";

// Deal with 16 bits
std::cout << ( to_binary( bin_number ) << 8 | to_binary( bin_number + 8 ) ) << std::endl;
constexpr unsigned binary_to_decimal(unsigned num)
{
    unsigned res = 0;

    while (num)
    {
        res = 10 * res + num % 10;
        num /= 10;
    }
    return res;
}
0b1010'1010 // or 0b10101010 without separator