Fast way to convert a binary number to a decimal number

前端 未结 5 1617
感情败类
感情败类 2021-02-05 17:29

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

相关标签:
5条回答
  • 2021-02-05 18:09

    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.

    Here a version C++14 compatible:

    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:

    0b1010'1010 // or 0b10101010 without separator
    
    0 讨论(0)
  • 2021-02-05 18:16

    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:

    #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.)

    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.

    0 讨论(0)
  • 2021-02-05 18:20

    If you know the number of binary digits that you're dealing with and it's always fixed and the 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:

    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.)

    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.

    0 讨论(0)
  • 2021-02-05 18:22

    Actually if you write unsigned int bin_number = 10101010, this is interpreted as a decimal number by the compiler.

    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...

    unsigned int i = BOOST_BINARY(10101010);
    std::cout << i; // This prints 170
    
    0 讨论(0)
  • 2021-02-05 18:26

    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.

    Example: std::cout << binary<10101010>::value;

    For run-time problem:

    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;
    }
    
    0 讨论(0)
提交回复
热议问题