打印输出:整数,表示2的幂

时间:2013-05-21 16:55:03

标签: c twos-complement

我参加了考试,从那以后我一直在努力。 你有一个整数数组(例如13,6,21,4),我需要做一个看起来像这样的输出:

13 = 2^3 + 2^2 + 2^0
6 = 2^2 + 2^1
21 = 2^4 + 2^2 + 2^0
4 = 2^2

这是我到目前为止所得到的。

#include <stdio.h>
#define MAX 100

int main() {
    int niz[MAX], nizb, n, i, ones, k;

    while(1) {
        printf("Array length: ");
        scanf("%d", &n);

        if (n<=0 || n>MAX) break;

        printf("Array elements: ");
        for(i=0;i<n;i++){
            scanf("%d", &niz[i]);
            if (niz[i] <=0) {
                printf("Error! Wrong value. Enter new one: ");
                scanf("%d", &niz[i]);
            }
        }

        for(i=0;i<n;i++) {
            nizb = niz[i];
            ones = 0;

            for(k=0; k < 16; k++) {
                //What should i do here?
            }

        }

    }
}

我被困在这里。我不知道我应该使用多少位,以及C如何看到这些整数位。我正在使用var'k'添加到格式为'2 ^ 3 + 2 ^ 2 ...'的字符串,其中k是'for'迭代的值。我假设整数的长度是16,但我真的不确定,因为我们在一张纸上这样做。

我想对每个人都说得好!

5 个答案:

答案 0 :(得分:2)

您可以使用sizeof运算符和CHAR_BIT来计算要使用的位数:

int bitsPerInt = sizeof(int) * CHAR_BIT;

CHAR_BITlimits.h中定义。

有了这个限制后,你可以使用按位&运算符来提取每个位:

for (k = bitsPerInt - 1; k >= 0; k--)
{
    if (nizb & (1U << k))
        // output
    else
        // don't
}

我会把细节留给你。

除此之外:看起来您正在尝试将niz用作数组,但您尚未将其声明为一个数组。这段代码甚至可以编译吗?此外,main的返回值应为int

答案 1 :(得分:1)

这是完全猜想,因为我对数学不是很好,但我想我会这样做:

 int potency = 0, base = 1;
 while(base < NumberInQuestion) {
     base *= 2;
     ++potency;
 }

循环结束后,您将知道仍然适合“数字”的最高效力。

 Number -= base/2; //Removes the base you just calculated from the number.
 printf("2^%d", potency);

冲洗并重复,直到Number降至0,最迟应为2 ^ 0。

对于您的用例,代码可能看起来像这样:

for(i=0; i < n; ++i) {
    int Number = niz[i];
    while(Number > 0) {
        int potency = 0, base = 1;
        do {               //Executes at least once, making a number of '1' possible.
            base *= 2;
            ++potency;
        } while(base < Number);
        Number -= base/2; //Reverts the last step you made, making the 'base' smaller than 'Number'.
        printf("2^%d", potency);
    }
}

有一种可能的选择,它可以让您更全面地了解事物并节省迭代次数。为此,我们使用两个步骤。

for(i=0; i < n; ++i) {
    int Number = niz[i];
    int potency = 0, base = 1;
    do {               //Executes at least once, making a number of '1' possible.
        base *= 2;
        ++potency;
    } while(base < Number);

    base /= 2;                      //Reverses the last iteration.

    //At this point, we know the maximum potency, which still fits into the number.
    //In regards of base 2, we know the Most Significant Bit.
    while(base > 0) {
        Number -= base;             //Removes the MSD (Most significant digit)
        printf("2^%d", potency);    //Prints your '1'.
        while(base > Number) {      //Executes at least once.
            base /= 2;              //Goes back one potency. (Ends at '0' latest.)
            --potency;              //For each potency (except for first), it's a '0'.
        }
    }
}

答案 2 :(得分:1)

不确定这与二元补码(这是表示负数的特定方式)有什么关系。你要做的是将一个整数表示为2的幂的总和,显然。这是我做的方式,这不一定比其他答案更好或更差......

void powersum(int n)
{ int powers[sizeof(int) << 3];
  int i;
  char *sep = "";

  printf("%d = ", n);

  powers[0] = 0;

  for (i = 0; n; n >>= 1, ++i)
    powers[i] = n & 1;

  while (--i >= 0)
  { if (powers[i])
    { printf("%s2^%d", sep, i);
      sep = " + ";
    }
  }

  printf("\n");
}
编辑:这是另一个不使用堆栈分配数组的版本,但是因为权衡必须更多地循环(每个位一次,而不是仅循环直到找到最高的1位) :

void powersum2(int n)
{ int i = (sizeof(int) << 3) - 2;
  int m = 1 << i;
  char *sep = "";

  printf("%d = ", n);

  while (m)
  { if (n & m)
    { printf("%s2^%d", sep, i);
      sep = " + ";
    }
    m >>= 1;
    --i;
  }

  printf("\n");
}

答案 3 :(得分:0)

quotient = niz[i];
 int k=0,c[MAX];

while(quotient!=0){

     binaryNumber[i++]= quotient % 2;  //this will convert your numbers to binary form 

     quotient = quotient / 2;          //and store in reverse in array

}
for(j = 0 ;j<i;j++)                 
 {                            
     if(binaryNumber[j]==1)  */e.g binary of 4 is stored in array as 001 ie 1 atpos2*/
  {  c[k]=j;
    k++;}
 }
  while(k--)
   printf("2^%d +",c[k]);  

答案 4 :(得分:0)

如果你能够容忍GCC依赖,那么对@ twalberg解决方案的破解真的很好而且很小;)

void powersum(int n)
{
    char *sep = "";
    printf("%d = ", n);

    while (n) {
        int pos = 31 - __builtin_clz(n);
        printf("%s2^%d", sep, pos);
        sep = " + ";
        n ^= 1 << pos;
    }

    printf("\n");
}