使用C的长长十进制二进制表示

时间:2018-02-07 11:19:40

标签: c long-integer

我一直试图使用 C编程

打印出长整数的二进制表示

我的代码是

#include<stdio.h>
#include <stdlib.h>
#include<limits.h>

int main()
{
    long long number, binaryRepresentation = 0, baseOfOne = 1, remainder;
    scanf("%lld", &number);
    while(number > 0) {
        remainder = number % 2;
        binaryRepresentation = binaryRepresentation + remainder * baseOfOne;
        baseOfOne *= 10;
        number = number / 2;
    }
    printf("%lld\n", binaryRepresentation);

}

当我提供 5 的输入时上述代码正常工作,当数字 9223372036854775807 (0x7FFFFFFFFFFFFFFF)时失败。

1.Test Case

5
101

2.Test Case

9223372036854775807
-1024819115206086201

6 个答案:

答案 0 :(得分:2)

使用一个否定数字来表示二进制数字永远不会特别好:你会因为一个非常小的输入而容易溢出,所有后续的算术操作都将毫无意义。

另一种方法是在出发时打印出数字,但使用递归技术,以便按照与处理数字相反的顺序打印数字:

#include <stdio.h>

unsigned long long output(unsigned long long n)
{
    unsigned long long m = n ? output(n / 2) : 0;
    printf("%d", (int)(n % 2));
    return m;
}

int main()
{
    unsigned long long number = 9223372036854775807;
    output(number);
    printf("\n");
}

输出:

0111111111111111111111111111111111111111111111111111111111111111

我还将类型更改为unsigned long long,其具有更好的定义位模式,%无论如何都为负数做了奇怪的事情。

实际上,我在这里所做的就是滥用堆栈作为存储真正的零和一组数据的方式。

答案 1 :(得分:1)

只是说明一些注释,最简单的方法是使用char数组来保存二进制数字。此外,在处理位时,逐位运算符更清晰一些。否则,我保留了你的基本代码结构。

int main()
{
    char bits[64];
    int i = 0;
    unsigned long long number;   // note the "unsigned" type here which makes more sense

    scanf("%lld", &number);

    while (number > 0) {
        bits[i++] = number & 1; // get the current bit
        number >>= 1;         // shift number right by 1 bit (divide by 2)
    }

    if ( i == 0 )   // The original number was 0!
        printf("0");

    for ( ; i > 0; i-- )
        printf("%d", bits[i]);  // or... putchar('0' + bits[i])

    printf("\n");
}

答案 2 :(得分:1)

Bathsheba's answer所述,您需要更多空间 如果您使用十进制数来表示类似的位序列,则可用。

由于您打算打印结果,因此最好一次只执行一次。我们可以通过创建仅具有最高位设置的掩码来实现此目的。为任何类型创建它的神奇之处在于补充该类型的零以获得&#34;所有类型&#34;数;然后我们减去一半(即1111 .... - 0111 ....)只得到一个位。然后我们可以沿着数字向右移动以依次确定每个位的状态。

这是使用该逻辑的重新制作版本,其他更改如下:

  • 我使用单独的函数,返回(如printf)打印的字符数。
  • 我接受无符号值,因为我们无论如何都忽略了负值。
  • 我从命令行处理参数 - 我倾向于发现在stdin上输入东西更方便。
#include <stdio.h>
#include <stdlib.h>

int print_binary(unsigned long long n)
{
    int printed = 0;
    /* ~ZERO - ~ZERO/2 is the value 1000... of ZERO's type */
    for (unsigned long long mask = ~0ull - ~0ull/2;  mask;  mask /= 2) {
        if (putc(n & mask ? '1' : '0', stdout) < 0)
            return EOF;
        else
            ++printed;
    }
    return printed;
}

int main(int argc, char **argv)
{
    for (int i = 1;  i < argc;  ++i) {
        print_binary(strtoull(argv[i], 0, 10));
        puts("");
    }
}

读者练习:

  • 避免打印前导零(提示:保留一个布尔标志,表示您已经看到第一个1,或者在打印前有一个单独的循环来移动蒙版)。别忘了检查print_binary(0)是否仍然产生输出!
  • 使用strtoull转换十进制字符串的输入值时检查错误。
  • 调整函数以写入字符数组而不是stdout。

答案 3 :(得分:0)

我不确定你真正想要实现的目标,但是这里有一些代码可以打印数字的二进制表示(将typedef更改为你想要的整数类型):

typedef int shift_t;
#define NBITS   (sizeof(shift_t)*8)

void printnum(shift_t num, int nbits)
{
    int k= (num&(1LL<<nbits))?1:0;
    printf("%d",k);
    if (nbits) printnum(num,nbits-1);
}
void test(void)
{
    shift_t l;
    l= -1;
    printnum(l,NBITS-1);
    printf("\n");
    l= (1<<(NBITS-2));
    printnum(l,NBITS-1);
    printf("\n");
    l= 5;
    printnum(l,NBITS-1);
    printf("\n");
}

答案 4 :(得分:0)

如果您不介意分别打印数字,可以使用以下方法:

#include<stdio.h>
#include <stdlib.h>
#include<limits.h>

void bindigit(long long num);

int main()
{
    long long number, binaryRepresentation = 0, baseOfOne = 1, remainder;
    scanf("%lld", &number);
    bindigit(number);
    printf("\n");

}

void bindigit(long long num) {
  int remainder;
  if (num < 2LL) {
    printf("%d",(int)num);
  } else {
    remainder = num % 2;
    bindigit(num/2);
    printf("%d",remainder);
  }
}

答案 5 :(得分:0)

最后,我自己尝试了一个代码,其中包含了您的代码中的创意,

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

int main() {
   unsigned long long number;
   int binaryRepresentation[70], remainder, counter, count = 0;
   scanf("%llu", &number);
   while(number > 0) {
       remainder = number % 2;
       binaryRepresentation[count++] = remainder;
       number = number / 2;
   }
   for(counter = count-1; counter >= 0; counter--) {
       printf("%d", binaryRepresentation[counter]);
   }
}