2011-02-28 75 views
3

我做了一个将数字转换为二进制的函数。由于某种原因,它无法正常工作。它给出错误的输出。输出为二进制格式,但它总是给出了以零结束二进制数错误的结果(至少这是我注意到..)在C++中转换为二进制

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; 
} 

请帮我解决它,这真是令人沮丧。 。

谢谢!

+4

这真的令人沮丧,因为数字已经是二进制形式,并且不需要转换。你可以做的是打印它的位,但互联网上有很多例子。 – 2011-02-28 16:10:38

+2

你正在做的是转换成一个十进制数字,看起来像二进制,但有错误的值。你的家庭作业到底是什么? – geoffspear 2011-02-28 16:12:08

+0

这是功课吗? – GWW 2011-02-28 16:15:40

回答

2
  1. 您正在反转这些位。
  2. 您不能使用x的剩余部分作为终止循环的指示符。

考虑例如4.

后第一循环迭代:

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

后第二循环迭代:

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

然后设置转换为1

尝试:

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 
} 

运行a波夫代码,其中x为unsigned char(8位)与值129(二进制10000001)

i = 8,无符号字符* 8的大小在第一循环开始迭代i将7.然后,我们采取x(129 )并将其右移7位,给出值1.这被或成converted,其变为1.接下来的迭代,我们将converted乘以10(所以现在是10)开始,然后我们将x右移6位值变为2)并与1进行AND运算(值变为0)。我们或0 converted,这是当时仍10. 3日 - 7日反复做同样的事情,converted乘以10和一个特定的位由x和或运算提取到converted。这些迭代之后,converted是1000000

在最后一次迭代中,第一converted乘以10,成为为10000000,我们转向x右侧0位,得到原始值129.我们,把X 1,这给值1. 1,然后将进行或运算converted,成为10000001.

+1

他并没有将遗体作为停止条件,我认为你的一段代码需要一些解释。我明白,但我怀疑具有基本C知识的人会。而且你错过了转换的初始化,这非常重要。 – krtek 2011-02-28 16:30:32

+0

你能解释最后一行吗?你为什么使用按位OR,AND和右移?还有,第一行的目的是什么(sizeof(x)* 8)? – Lockhead 2011-02-28 20:18:36

+0

编辑更多详细信息 – Erik 2011-02-28 20:23:31

0

你实际上是颠倒的二进制数! to_binary(2)将返回01,而不是10.当初始0es被截断,它的外观一样1.

怎么做这种方式:

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

你这样做错了;)

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

的仍然是第一部的是二进制形式的最右边的位,与你的功能就成了最左边位。

你可以做这样的事情:

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; 
} 

编辑:由CygnusX1提出的代码是多一点点效率,但不够全面,我认为,我就劝他服用版本。

改进:我改变了while循环的停止条件,所以我们可以在最后删除添加x的行。

+0

+1仅用于*“你做错了;)”* – BlackBear 2011-02-28 18:53:32

0

如果你想显示你数为二进制,你需要把它格式化为一个字符串。我所知道的最简单的方法是使用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; 
}; 

从这个程序的输出是:

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

如果你的目的只是显示他们为他们的二进制表示,那么你可以尝试itoastd::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; 
} 
+2

'itoa'是一个在许多平台上都不可用的非标准函数(我只在Windows上看过它)。 – 2011-02-28 21:26:49

3

使用std: :bitset做翻译:

#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"; 

} 
0
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; 
    } 
} 
0

这是一个简单的解决方案。

#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; 
}