2017-04-05 125 views
0

我想检查数组中的数是否是2的幂。检查数是否是2的幂,如果输入是数字

我写了下面的代码,但它不起作用,它跳过检查数字是2的幂的部分并打印最后一句。

此外,如果有人可以帮助我如何检查输入是否是一个数字,而不是任何其他字符。 谢谢! 更新两件事电源工作,但我还没有弄清楚如何检查,如果输入的是数字,而不是任何其他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; 
} 
+0

欢迎来到Stack Overflow!请[编辑]你的代码,以减少它到你的问题[mcve]。您当前的代码包含很多与您的问题相关的代码 - 通常,最小样本看起来与单元测试相似:只执行一项任务,输入值指定为可重现性。没有必要为输入数组分配存储空间来展示你的问题(但是如果你这样做了,你真的应该在'malloc()'的参数中使用它之前检查'x'是否是正数,或者(更好)声明它作为一个无符号类型 –

回答

1

你的例子中有很多是偶然的问题。例如,分配一个数组和读取用户输入只是找到解决方案的分心。首先集中调试你的算法:

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

现在,你可以改进该函数,直到它给出正确的结果。简单的解决方法是用n == 1替换n == 0。现在你可以添加更多的测试,运行程序为您添加的每个之一:

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

一旦你有了一定的信心你的功能,你可以使用它在你的程序来处理数组。


当你引入一个函数读取输入,你要检查x是不使用的参数malloc()之前负。更好的办法是通过使用无符号类型来确保它不是负数:

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

'%u'转换说明符与可选的有符号十进制整数相匹配,并应用适当的转换。如果输入一个负值,它将被转换为'unsigned',这会导致令人惊讶的分配。 –

+1

这是一个很好的观点,@大卫 - 可能值得一些理智的检查(或只是取决于结果太大而无法分配)。实际上,这只是证明了'scanf()'及其同类的脆弱性。 –

3

您的两个电源检查是错误的:你把一路下降到1,但以下if错误地检查numbers[k]==0

的检查应numbers[k]==1代替,因为当你从你结束了2 二的幂,这是1划分出所有三三两两。

注意:通过使用this Q&A中描述的位技巧,您可以检查一个数是否是没有循环的幂。

+0

我改变了它,但它仍然无法正常工作!例如,如果我键入ine数字对象例如:2,但不适用于多个输入:\ – lauren

+0

@lauren它的工作完美我([演示](http://ideone.com/oTUhdi))。 – dasblinkenlight

+0

嗨,我会道歉,因为我认为它没有工作,因为昨晚它真的没有工作,但今天它确实:\虽然我改变了没有 !也许我昨​​天晚上累得累了:|谢谢 – lauren