C++ - Decimal to binary converting

后端 未结 29 3465
一向
一向 2020-11-28 18:53

I wrote a \'simple\' (it took me 30 minutes) program that converts decimal number to binary. I am SURE that there\'s a lot simpler way so can you show me? Here\'s the code:<

相关标签:
29条回答
  • 2020-11-28 19:33

    Okay.. I might be a bit new to C++, but I feel the above examples don't quite get the job done right.

    Here's my take on this situation.

    char* DecimalToBinary(unsigned __int64 value, int bit_precision)
    {
        int length = (bit_precision + 7) >> 3 << 3;
        static char* binary = new char[1 + length];
        int begin = length - bit_precision;
        unsigned __int64 bit_value = 1;
        for (int n = length; --n >= begin; )
        {
            binary[n] = 48 | ((value & bit_value) == bit_value);
            bit_value <<= 1;
        }
        for (int n = begin; --n >= 0; )
            binary[n] = 48;
    
        binary[length] = 0;
        return binary;
    }
    

    @value = The Value we are checking.

    @bit_precision = The highest left most bit to check for.

    @Length = The Maximum Byte Block Size. E.g. 7 = 1 Byte and 9 = 2 Byte, but we represent this in form of bits so 1 Byte = 8 Bits.

    @binary = just some dumb name I gave to call the array of chars we are setting. We set this to static so it won't be recreated with every call. For simply getting a result and display it then this works good, but if let's say you wanted to display multiple results on a UI they would all show up as the last result. This can be fixed by removing static, but make sure you delete [] the results when you are done with it.

    @begin = This is the lowest index that we are checking. Everything beyond this point is ignored. Or as shown in 2nd loop set to 0.

    @first loop - Here we set the value to 48 and basically add a 0 or 1 to 48 based on the bool value of (value & bit_value) == bit_value. If this is true the char is set to 49. If this is false the char is set to 48. Then we shift the bit_value or basically multiply it by 2.

    @second loop - Here we set all the indexes we ignored to 48 or '0'.

    SOME EXAMPLE OUTPUTS!!!

    int main()
    {
        int val = -1;
        std::cout << DecimalToBinary(val, 1) << '\n';
        std::cout << DecimalToBinary(val, 3) << '\n';
        std::cout << DecimalToBinary(val, 7) << '\n';
        std::cout << DecimalToBinary(val, 33) << '\n';
        std::cout << DecimalToBinary(val, 64) << '\n';
        std::cout << "\nPress any key to continue. . .";
        std::cin.ignore();
        return 0;
    }
    
    00000001 //Value = 2^1 - 1
    00000111 //Value = 2^3 - 1.
    01111111 //Value = 2^7 - 1.
    0000000111111111111111111111111111111111 //Value = 2^33 - 1.
    1111111111111111111111111111111111111111111111111111111111111111 //Value = 2^64 - 1.
    

    SPEED TESTS

    Original Question's Answer: "Method: toBinary(int);"

    Executions: 10,000 , Total Time (Milli): 4701.15 , Average Time (Nanoseconds): 470114

    My Version: "Method: DecimalToBinary(int, int);"

    //Using 64 Bit Precision.

    Executions: 10,000,000 , Total Time (Milli): 3386 , Average Time (Nanoseconds): 338

    //Using 1 Bit Precision.

    Executions: 10,000,000, Total Time (Milli): 634, Average Time (Nanoseconds): 63

    0 讨论(0)
  • 2020-11-28 19:34

    here a simple converter by using std::string as container. it allows a negative value.

    #include <iostream>
    #include <string>
    #include <limits>
    
    int main()
    {
        int x = -14;
    
        int n = std::numeric_limits<int>::digits - 1;
    
        std::string s;
        s.reserve(n + 1);
    
        do
            s.push_back(((x >> n) & 1) + '0');
        while(--n > -1);
    
        std::cout << s << '\n';
    }
    
    0 讨论(0)
  • 2020-11-28 19:34

    There is in fact a very simple way to do so. What we do is using a recursive function which is given the number (int) in the parameter. It is pretty easy to understand. You can add other conditions/variations too. Here is the code:

    int binary(int num)
    {
        int rem;
        if (num <= 1)
            {
                cout << num;
                return num;
            }
        rem = num % 2;
        binary(num / 2);
        cout << rem;
        return rem;
    }
    
    0 讨论(0)
  • 2020-11-28 19:38

    Below is simple C code that converts binary to decimal and back again. I wrote it long ago for a project in which the target was an embedded processor and the development tools had a stdlib that was way too big for the firmware ROM.

    This is generic C code that does not use any library, nor does it use division or the remainder (%) operator (which is slow on some embedded processors), nor does it use any floating point, nor does it use any table lookup nor emulate any BCD arithmetic. What it does make use of is the type long long, more specifically unsigned long long (or uint64_t), so if your embedded processor (and the C compiler that goes with it) cannot do 64-bit integer arithmetic, this code is not for your application. Otherwise, I think this is production quality C code (maybe after changing long to int32_t and unsigned long long to uint64_t). I have run this overnight to test it for every 2³² signed integer values and there is no error in conversion in either direction.

    We had a C compiler/linker that could generate executables and we needed to do what we could do without any stdlib (which was a pig). So no printf() nor scanf(). Not even an sprintf() nor sscanf(). But we still had a user interface and had to convert base-10 numbers into binary and back. (We also made up our own malloc()-like utility also and our own transcendental math functions too.)

    So this was how I did it (the main program and calls to stdlib were there for testing this thing on my mac, not for the embedded code). Also, because some older dev systems don't recognize "int64_t" and "uint64_t" and similar types, the types long long and unsigned long long are used and assumed to be the same. And long is assumed to be 32 bits. I guess I could have typedefed it.

    // returns an error code, 0 if no error,
    // -1 if too big, -2 for other formatting errors
    int decimal_to_binary(char *dec, long *bin)
        {
        int i = 0;
        
        int past_leading_space = 0;
        while (i <= 64 && !past_leading_space)        // first get past leading spaces
            {
            if (dec[i] == ' ')
                {
                i++;
                }
             else
                {
                past_leading_space = 1;
                }
            }
        if (!past_leading_space)
            {
            return -2;                                // 64 leading spaces does not a number make
            }
        // at this point the only legitimate remaining
        // chars are decimal digits or a leading plus or minus sign
    
        int negative = 0;
        if (dec[i] == '-')
            {
            negative = 1;
            i++;
            }
         else if (dec[i] == '+')
            {
            i++;                                    // do nothing but go on to next char
            }
        // now the only legitimate chars are decimal digits
        if (dec[i] == '\0')
            {
            return -2;                              // there needs to be at least one good 
            }                                       // digit before terminating string
        
        unsigned long abs_bin = 0;
        while (i <= 64 && dec[i] != '\0')
            {
            if ( dec[i] >= '0' && dec[i] <= '9' )
                {
                if (abs_bin > 214748364)
                    {
                    return -1;                                // this is going to be too big
                    }
                abs_bin *= 10;                                // previous value gets bumped to the left one digit...                
                abs_bin += (unsigned long)(dec[i] - '0');     // ... and a new digit appended to the right
                i++;
                }
             else
                {
                return -2;                                    // not a legit digit in text string
                }
            }
        
        if (dec[i] != '\0')
            {
            return -2;                                // not terminated string in 64 chars
            }
        
        if (negative)
            {
            if (abs_bin > 2147483648)
                {
                return -1;                            // too big
                }
            *bin = -(long)abs_bin;
            }
         else
            {
            if (abs_bin > 2147483647)
                {
                return -1;                            // too big
                }
            *bin = (long)abs_bin;
            }
        
        return 0;
        }
    
    
    void binary_to_decimal(char *dec, long bin)
        {
        unsigned long long acc;                // 64-bit unsigned integer
        
        if (bin < 0)
            {
            *(dec++) = '-';                    // leading minus sign
            bin = -bin;                        // make bin value positive
            }
        
        acc = 989312855LL*(unsigned long)bin;        // very nearly 0.2303423488 * 2^32
        acc += 0x00000000FFFFFFFFLL;                 // we need to round up
        acc >>= 32;
        acc += 57646075LL*(unsigned long)bin;
        // (2^59)/(10^10)  =  57646075.2303423488  =  57646075 + (989312854.979825)/(2^32)  
        
        int past_leading_zeros = 0;
        for (int i=9; i>=0; i--)            // maximum number of digits is 10
            {
            acc <<= 1;
            acc += (acc<<2);                // an efficient way to multiply a long long by 10
    //      acc *= 10;
            
            unsigned int digit = (unsigned int)(acc >> 59);        // the digit we want is in bits 59 - 62
            
            if (digit > 0)
                {
                past_leading_zeros = 1;
                }
            
            if (past_leading_zeros)
                {
                *(dec++) = '0' + digit;
                }
            
            acc &= 0x07FFFFFFFFFFFFFFLL;    // mask off this digit and go on to the next digit
            }
        
        if (!past_leading_zeros)            // if all digits are zero ...
            {
            *(dec++) = '0';                 // ... put in at least one zero digit
            }
        
        *dec = '\0';                        // terminate string
        }
    
    
    #if 1
    
    #include <stdlib.h>
    #include <stdio.h>
    int main (int argc, const char* argv[])
        {
        char dec[64];
        long bin, result1, result2;
        unsigned long num_errors;
        long long long_long_bin;
        
        num_errors = 0;
        for (long_long_bin=-2147483648LL; long_long_bin<=2147483647LL; long_long_bin++)
            {
            bin = (long)long_long_bin;
            if ((bin&0x00FFFFFFL) == 0)
                {
                printf("bin = %ld \n", bin);        // this is to tell us that things are moving along
                }
            binary_to_decimal(dec, bin);
            decimal_to_binary(dec, &result1);
            sscanf(dec, "%ld", &result2);            // decimal_to_binary() should do the same as this sscanf()
            
            if (bin != result1 || bin != result2)
                {
                num_errors++;
                printf("bin = %ld, result1 = %ld, result2 = %ld, num_errors = %ld, dec = %s \n",
                    bin, result1, result2, num_errors, dec);
                }
            }
        
        printf("num_errors = %ld \n", num_errors);
        
        return 0;
        }
    
    #else
    
    #include <stdlib.h>
    #include <stdio.h>
    int main (int argc, const char* argv[])
        {
        char dec[64];
        long bin;
        
        printf("bin = ");
        scanf("%ld", &bin);
        while (bin != 0)
            {
            binary_to_decimal(dec, bin);
            printf("dec = %s \n", dec);
            printf("bin = ");
            scanf("%ld", &bin);
            }
        
        return 0;
        }
    
    #endif
    
    0 讨论(0)
  • 2020-11-28 19:39

    Here is modern variant that can be used for ints of different sizes.

    #include <type_traits>
    #include <bitset>
    
    template<typename T>
    std::enable_if_t<std::is_integral_v<T>,std::string>
    encode_binary(T i){
        return std::bitset<sizeof(T) * 8>(i).to_string();
    }
    
    0 讨论(0)
  • 2020-11-28 19:41

    This is a more simple program than ever

    //Program to convert Decimal into Binary
    #include<iostream>
    using namespace std;
    int main()
    {
        long int dec;
        int rem,i,j,bin[100],count=-1;
        again:
        cout<<"ENTER THE DECIMAL NUMBER:- ";
        cin>>dec;//input of Decimal
        if(dec<0)
        {
            cout<<"PLEASE ENTER A POSITIVE DECIMAL";
            goto again;
        }
        else
            {
            cout<<"\nIT's BINARY FORM IS:- ";
            for(i=0;dec!=0;i++)//making array of binary, but reversed
            {
                rem=dec%2;
                bin[i]=rem;
                dec=dec/2;
                count++;
            }
            for(j=count;j>=0;j--)//reversed binary is printed in correct order
            {
                cout<<bin[j];
            }
        }
        return 0; 
    }
    
    0 讨论(0)
提交回复
热议问题