我必须尽快将二进制数字(如unsigned int bin_number = 10101010
)转换为十进制表示(即170
)?什么是最好的算法?
答案 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>
当然,它非常具体而且不够灵活,但是它可以完成工作而我不确定你会得到更快的速度。