0

I want to check if the numbers in an array are a power of two.

I wrote the following code, but it doesn't work it skips the part that checks if the number is the power of two and prints the last sentence.

Also, if someone can help me in how to check if the input is a number and not any other character. Thank you! update the power of two thing is working but i still haven't figure out how to check if the input is a number and not any other characher

   #include <stdio.h>
#include <stdlib.h>
int main()
{
    int x;
    int i;
    int k;
    int count=0;
    int a;
    int sum=0;
    printf("Enter size of input:\n");
    scanf("%d",&x);
    int *numbers=malloc(sizeof(int)*x);
    if (x<0){
      printf("Invalid size\n");
    }
    else {
       printf("Enter numbers:\n");
       for(i=0;i<x;++i){
         scanf("%d",&numbers[i]);

       }
    }
    for(k=0;k<x;++k)
    {
        count=0;
        a=numbers[k];
        while (((numbers[k] % 2) == 0) && numbers[k] > 1){ /* While x is even and > 1 */
             numbers[k]/= 2;
             ++count;
        }
        if (numbers[k]==1&&a!=1){
             printf("The number %d is a power of 2:%d=2^%d\n",a,a,count);
             sum+=count;
        }
    }
    printf("Total exponent num is %d\n",sum);
  return 0;
}
lauren
  • 49
  • 5
  • Welcome to Stack Overflow! Please [edit] your code to reduce it to a [mcve] of your problem. Your current code includes much that is peripheral to your problem - a minimal sample normally looks similar to a good unit test: only performing one task, with input values specified for reproducibility. There's no need to allocate storage for an array of inputs to demonstrate your problem (but if you do, you really ought to check that `x` is positive before using it in the argument to `malloc()`, or (better) declare it as an unsigned type. – Toby Speight Apr 05 '17 at 08:07

2 Answers2

3

Your check for the power of two is wrong: you divide out two all the way down to 1, but the following if incorrectly checks numbers[k]==0.

The check should be numbers[k]==1 instead, because when you divide out all twos from a power of two you end up with 20, which is 1.

Note: You can check if a number is a power of two without a loop by using a bit trick described in this Q&A.

Community
  • 1
  • 1
Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • i changed it but it is still not working! it works for example if i type ine number foe example:2 , but doesn't work for more than one input :\ – lauren Apr 05 '17 at 00:34
  • @lauren It worked perfectly for me ([demo](http://ideone.com/oTUhdi)). – Sergey Kalinichenko Apr 05 '17 at 00:50
  • hi i am gonna apologize because i saied it didn't work because last night it honestly didn't work but today it does :\ although i changed nothing ! maybe i was just tired tired last night :| thank you – lauren Apr 05 '17 at 11:11
  • but i still haven't figure out how to check if the input is a number and not any other characher – lauren Apr 05 '17 at 11:15
  • @lauren Check [this Q&A](http://stackoverflow.com/a/14099507/335858) for an explanation of how to read an `int` and skip unwanted characters. This isn't simple, but the accepted answer provides a very good explanation. – Sergey Kalinichenko Apr 05 '17 at 11:25
  • thak you it worked ! – lauren Apr 05 '17 at 21:53
  • @lauren You are welcome! If the answer works for you, please consider accepting it by clicking the gray check mark next to it. This would let other site visitors know that you are no longer actively looking for an improved answer to the question, and earn you a new badge on Stack Overflow. – Sergey Kalinichenko Apr 06 '17 at 01:06
1

There's much in your example that's incidental to the problem. For example, allocating an array and reading user input is just a distraction from finding the solution. Concentrate first on debugging your algorithm:

#include <stdbool.h>

bool is_power_of_two(int n)
{
        while (n % 2 == 0 && n > 1){ /* While x is even and > 1 */
             n/= 2;
        }
        return n == 0;
}

int main()
{
    return !is_power_of_two(2);
}

Now, you can refine that function until it gives the correct result. The simple fix is to replace n == 0 with n == 1. Now you can add more tests, running the program as you add each one:

int main()
{
    return  is_power_of_two(0)
        +  !is_power_of_two(1)
        +  !is_power_of_two(2)
        +   is_power_of_two(3)
        +  !is_power_of_two(4)
        /* negative numbers can never be an exact power of a positive */
        +   is_power_of_two(-1)
        +   is_power_of_two(-2)
        +   is_power_of_two(-3);
}

Once you have some confidence in your function, you can then use it in your program to process arrays.


When you do introduce a function to read input, you'll want to check that x isn't negative before using in the argument to malloc(). Better would be to ensure it's not negative, by using an unsigned type:

unsigned int x;
printf("Enter size of input:\n");
if (scanf("%u", &x) != 1) {
    fprintf(stderr, "That's not a valid size!\n");
    return EXIT_FAILURE;
}
int *numbers = malloc(x * sizeof *numbers);
if (!numbers) {
    fprintf(stderr, "Couldn't allocate memory for %u numbers!\n", x);
    return EXIT_FAILURE;
}
Toby Speight
  • 27,591
  • 48
  • 66
  • 103
  • The `%u` conversion specifier matches an optionally signed decimal integer, and applies the appropriate conversion. If a negative value is entered, it is converted to `unsigned`, leading to a surprising allocation here. – ad absurdum Apr 05 '17 at 14:28
  • 1
    That's a good point, @David - possibly worth some sanity check (or just depend on the result being too big to allocate). Actually, that just demonstrates the fragility of `scanf()` and its ilk. – Toby Speight Apr 05 '17 at 14:37