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