C++ 将二进制数转换为十进制数的快速方法
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10949491/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Fast way to convert a binary number to a decimal number
提问by Nick
I have to convert a binary number like for example unsigned int bin_number = 10101010
into its decimal representation (i.e. 170
) as quickly as possible? What is the best algorithm?
我必须尽快将二进制数(例如)unsigned int bin_number = 10101010
转换为其十进制表示形式(即170
)?最好的算法是什么?
回答by gliderkite
Using templates you can solve this problem at compile-time.
使用模板可以在编译时解决这个问题。
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; };
The binary template is instantiated again with a smaller num
, until num
reaches zero and the specialization is used as a termination condition.
二进制模板再次使用较小的num
,实例化,直到num
达到零并且特化用作终止条件。
Example: std::cout << binary<10101010>::value;
例子: std::cout << binary<10101010>::value;
For run-timeproblem:
对于运行时问题:
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;
}
回答by Christian Rau
Well, if this "number" is actually a string gotten from some source (read from a file or from a user) that you converted into a number (thinking it to be more appropriate for an actual number), which is quite likely, you can use a std::bitset
to do the conversion:
好吧,如果这个“数字”实际上是从某个来源(从文件或用户处读取)获得的字符串,您将其转换为数字(认为它更适合实际数字),这很可能,您可以使用 astd::bitset
进行转换:
#include <bitset>
unsigned int number = std::bitset<32>("10101010").to_ulong();
(Of course the 32
here is implementation-defined and might be more appropriately written as std::numeric_limits<unsigned int>::digits
.)
(当然,32
这里是实现定义的,可能更恰当地写成std::numeric_limits<unsigned int>::digits
.)
But if it is really a number (integer variable) in the (very) first place you could do:
但是,如果它确实是(非常)第一位的数字(整数变量),您可以这样做:
#include <string>
unsigned int number = std::bitset<32>(std::to_string(bin_number)).to_ulong();
(using C++11's to_string
) But this will probably not be the most efficient way anymore, as others have presented more efficient algorithms based on numbers. But as said, I doubt that you really get this number as an actual integer variable in the very first place, but rather read it from some text file or from the user.
(使用 C++11 的to_string
)但这可能不再是最有效的方法,因为其他人已经提出了基于数字的更有效的算法。但如前所述,我怀疑您是否真的将这个数字作为实际的整数变量放在首位,而是从某个文本文件或用户那里读取它。
回答by Aurel
Actually if you write unsigned int bin_number = 10101010
, this is interpreted as a decimal number by the compiler.
实际上,如果您编写unsigned int bin_number = 10101010
,则编译器会将其解释为十进制数。
If you want to write a binary literal in your source code, you should use BOOST_BINARY
. Then, you just need to print it using cout
, decimal is the default...
如果要在源代码中编写二进制文字,则应使用BOOST_BINARY
. 然后,您只需要使用 打印它cout
,十进制是默认值...
unsigned int i = BOOST_BINARY(10101010);
std::cout << i; // This prints 170
回答by Jarod42
Since C++11 (even if C++11 is more limited than C++14 in that regard), function can be constexpr
so avoid necessity of template
to have compile time value.
由于 C++11(即使 C++11 在这方面比 C++14 更受限制),函数constexpr
可以避免template
具有编译时值的必要性。
Here a version C++14 compatible:
这里兼容 C++14 版本:
constexpr unsigned binary_to_decimal(unsigned num)
{
unsigned res = 0;
while (num)
{
res = 10 * res + num % 10;
num /= 10;
}
return res;
}
And for literals, you can even use binary literals since C++14:
对于文字,您甚至可以使用自 C++14 以来的二进制文字:
0b1010'1010 // or 0b10101010 without separator
回答by Component 10
If you know the number of binary digits that you're dealing with andit's always fixed andthe binary number comes in a string (as it would if read from a file or stdin) at runtime (i.e. compile time conversion not possible) then you could adopt this approach:
如果你知道你正在处理的二进制数字的数量并且它总是固定的并且二进制数字在运行时出现在一个字符串中(就像从文件或标准输入读取一样)(即编译时转换不可能)那么你可以采用这种方法:
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 );
}
This assumes an fixed eight digit binary number. called like this:
这假定一个固定的八位二进制数。像这样调用:
std::cout << to_binary("10101010") << std::endl;
If you had a sixteen bit number you could still use it:
如果你有一个 16 位数字,你仍然可以使用它:
const char* bin_number = "1010101010101010";
// Deal with 16 bits
std::cout << ( to_binary( bin_number ) << 8 | to_binary( bin_number + 8 ) ) << std::endl;
Note that there is clearly no bounds checking here and I'm relying on the fact that the LSB of '1' is always 1 and '0' is always 0 (so not validating that it's actually a binary input.)
请注意,这里显然没有边界检查,我依赖于“1”的 LSB 始终为 1 而“0”始终为 0 的事实(因此无法验证它实际上是二进制输入。)
Naturally, it's pretty specific and not very flexible, but it does the job and I'm not sure that you'd get much faster.
自然,它非常具体且不是很灵活,但它可以完成工作,而且我不确定您是否会变得更快。