簡體   English   中英

將二進制數轉換為十進制數的快速方法

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM