[英]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.