开发者

Converting to binary in C++

开发者 https://www.devze.com 2023-02-14 02:57 出处:网络
I made a function that converts numbers to binary. For some reason it\'s not working. It gives the wrong output. The output is in binary format, but it always gives the wrong result for binary numbers

I made a function that converts numbers to binary. For some reason it's not working. It gives the wrong output. The output is in binary format, but it always gives the wrong result for binary numbers that end with a zero(at least that's what I noticed..)

unsigned long long to_binary(unsigned long long x)
{
    int rem;
    unsigned long long converted = 0;

    while (x > 1)
    {
        rem = x % 2;
        x /= 2;
        converted += rem;
        converted *= 10;
    }

    converted += x;

    return 开发者_运维知识库converted;
}

Please help me fix it, this is really frustrating..

Thanks!


Use std::bitset to do the translation:

#include <iostream>
#include <bitset>
#include <limits.h>

int main()
{
    int     val;
    std::cin >> val;

    std::bitset<sizeof(int) * CHAR_BIT>    bits(val);
    std::cout << bits << "\n";

}


  1. You're reversing the bits.
  2. You cannot use the remains of x as an indicator when to terminate the loop.

Consider e.g. 4.

After first loop iteration:

rem == 0
converted == 0
x == 2

After second loop iteration:

rem == 0
converted == 0
x == 1

And then you set converted to 1.

Try:

int i = sizeof(x) * 8; // i is now number of bits in x
while (i>0) {
  --i;
  converted *= 10;
  converted |= (x >> i) & 1;
  // Shift x right to get bit number i in the rightmost position, 
  // then and with 1 to remove any bits left of bit number i,
  // and finally or it into the rightmost position in converted
}

Running the above code with x as an unsigned char (8 bits) with value 129 (binary 10000001)

Starting with i = 8, size of unsigned char * 8. In the first loop iteration i will be 7. We then take x (129) and shift it right 7 bits, that gives the value 1. This is OR'ed into converted which becomes 1. Next iteration, we start by multiplying converted with 10 (so now it's 10), we then shift x 6 bits right (value becomes 2) and ANDs it with 1 (value becomes 0). We OR 0 with converted, which is then still 10. 3rd-7th iteration do the same thing, converted is multiplied with 10 and one specific bit is extracted from x and OR'ed into converted. After these iterations, converted is 1000000.

In the last iteration, first converted is multiplied with 10 and becomes 10000000, we shift x right 0 bits, yielding the original value 129. We AND x with 1, this gives the value 1. 1 is then OR'ed into converted, which becomes 10000001.


You're doing it wrong ;)

http://www.bellaonline.com/articles/art31011.asp

The remain of the first division is the rightmost bit in the binary form, with your function it becomes the leftmost bit.

You can do something like this :

unsigned long long to_binary(unsigned long long x)
{
    int rem;
    unsigned long long converted = 0;
    unsigned long long multiplicator = 1;

    while (x > 0)
    {
        rem = x % 2;
        x /= 2;
        converted += rem * multiplicator;
        multiplicator *= 10;
    }

    return converted;
}

edit: the code proposed by CygnusX1 is a little bit more efficient, but less comprehensive I think, I'll advise taking his version.

improvement : I changed the stop condition of the while loop, so we can remove the line adding x at the end.


You are actually reversing the binary number! to_binary(2) will return 01, instead of 10. When initial 0es are truncated, it will look the same as 1.

how about doing it this way:

unsigned long long digit = 1;
while (x>0) {
  if (x%2)
    converted+=digit;
  x/=2;
  digit*=10;
}


What about std::bitset?

http://www.cplusplus.com/reference/stl/bitset/to_string/


If you want to display you number as binary, you need to format it as a string. The easiest way to do this that I know of is to use the STL bitset.

#include <bitset>
#include <iostream>
#include <sstream>

typedef std::bitset<64> bitset64;


std::string to_binary(const unsigned long long int& n)
{
        const static int mask = 0xffffffff;
        int upper = (n >> 32) & mask;
        int lower = n & mask;
        bitset64 upper_bs(upper);
        bitset64 lower_bs(lower);
        bitset64 result = (upper_bs << 32) | lower_bs;
        std::stringstream ss;
        ss << result;
        return ss.str();
};

int main()
{
        for(int i = 0; i < 10; ++i)
        {
                std::cout << i << ": " << to_binary(i) << "\n";
        };
        return 1;
};

The output from this program is:

0: 0000000000000000000000000000000000000000000000000000000000000000
1: 0000000000000000000000000000000000000000000000000000000000000001
2: 0000000000000000000000000000000000000000000000000000000000000010
3: 0000000000000000000000000000000000000000000000000000000000000011
4: 0000000000000000000000000000000000000000000000000000000000000100
5: 0000000000000000000000000000000000000000000000000000000000000101
6: 0000000000000000000000000000000000000000000000000000000000000110
7: 0000000000000000000000000000000000000000000000000000000000000111
8: 0000000000000000000000000000000000000000000000000000000000001000
9: 0000000000000000000000000000000000000000000000000000000000001001


If your purpose is only display them as their binary representation, then you may try itoa or std::bitset

#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <bitset>

using namespace std;

int main()
{
    unsigned long long x = 1234567890;

    // c way
    char buffer[sizeof(x) * 8];
    itoa (x, buffer, 2);
    printf ("binary: %s\n",buffer);

    // c++ way
    cout << bitset<numeric_limits<unsigned long long>::digits>(x) << endl;

    return EXIT_SUCCESS;
}


void To(long long num,char *buff,int base)
{
    if(buff==NULL)      return;
    long long m=0,no=num,i=1;

    while((no/=base)>0) i++;
    buff[i]='\0';

    no=num;
    while(no>0)
    {
        m=no%base;
        no=no/base;
        buff[--i]=(m>9)?((base==16)?('A' + m - 10):m):m+48;
    }
}


Here is a simple solution.

#include <iostream>
using namespace std;
int main()
{
    int num=241; //Assuming 16 bit integer
    for(int i=15; i>=0; i--) cout<<((num >> i) & 1);
    cout<<endl;
    for(int i=0; i<16; i++) cout<<((num >> i) & 1);
    cout<<endl;
    return 0;
}
0

精彩评论

暂无评论...
验证码 换一张
取 消