Member 13106348 Ответов: 2

Проверьте, является ли число степенью двойки и является ли вход числом


я хочу проверить, являются ли числа в массиве степенью 2,
я написал следующий код, но он не работает, он пропускает ту часть, которая чикает, если число равно степени двух, и печатает последнее предложение.
кроме того, если кто-то может помочь мне в том, как проверить, является ли вход номером, а не каким-либо другим charctar.
Спасибо!

Что я уже пробовал:

#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]==0){
             printf("The number %d is a power of 2:%d=2^%d\n",a,a,count);
             sum+=a;
        }
    }
    printf("Total exponent num is %d\n",sum);
  return 0;
}

PIEBALDconsult

Пятно отладки должно сделать свое дело. Я особенно думаю, что вы должны изучить числа[k] после цикла while и перед тестированием на ноль.

Member 13106348

я попробовал отладку, но ничего не вышло :\ я до сих пор не знаю проблемы .. я изменил if statmnet на if (numbers[k]==0), и теперь он работает только для ввода одного числа.

PIEBALDconsult

А что было раньше?
С каким набором чисел вы тестировали? Какой результат вы получили?

[no name]

Да, я понимаю, что ты имеешь в виду. Вы запустили программу и думали, что отлаживаете ее, но не потрудились использовать точки останова, чтобы пройти через ваш код и изучить переменные. Итак, нет, вы не отлаживали свою программу, чтобы увидеть, что она делает.

[no name]

Изучение того, как использовать отладчик, - это действительно полезный навык, которому вы должны научиться.

Member 13106348

могу ли я выучить его за полдня ?

PIEBALDconsult

Нет. Но вы можете начать.

nv3

Сначала, конечно, отладьте свой код. Как только вы это сделаете, обратите внимание, что существует гораздо более эффективный метод проверки того, является ли число степенью 2:

int x;

если (x & (x-1) == 0)
// да, это сила двух

Я оставляю это на ваше усмотрение, чтобы доказать, почему и как этот маленький трюк работает.

PIEBALDconsult

Но скажет ли он вам экспоненту?

nv3

Нет, это не так. Просто независимо от того, является ли число степенью двойки или нет. Показатель степени также может быть определен в куске линейного кода с помощью 12-битной таблицы поиска и трех rsp. шесть сдвигов.

2 Ответов

Рейтинг:
7

CPallini

Вы знаете, что язык программирования Си не мешает вам определять функции...
Попробуй

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


int powoftwo(int x)
{
  int count;

  for ( count = 0; x && ((x & 1) == 0); ++count )
    x >>= 1;

  if ( x == 1)
    return count;

  return -1;
}


int main()
{
    int x;
    int i;
    int k;
    printf("Enter size of input:\n");
    scanf("%d",&x);
    int *numbers= NULL;
    if (x<0){
      printf("Invalid size\n");
      return -1;
    }
    else
    {
      numbers = malloc(sizeof(int)*x);
      if ( ! numbers)
      {
        printf("memory allocation failure\n");
      }

       printf("Enter numbers:\n");
       for(i=0;i<x;++i){
         scanf("%d",&numbers[i]);
       }
    }
    for(k=0;k<x;++k)
    {
      int exp = powoftwo(numbers[k]);
      if ( exp > 0)
        printf("The number %d is a power of 2:%d=2^%d\n", numbers[k],numbers[k],exp);

    }
    free(numbers);
    return 0;
}


PIEBALDconsult

А получение показателей?

CPallini

powoftwo возвращается
-1, если переданное значение не является степенью двойки.
показатель степени, если переданное значение равно степени двух.

W∴ Balboos, GHB

Поправьте меня, если я ошибаюсь, но число-это только степень двух, если один и только один бит установлен в 1. Итак, вам нужно проверить все биты в int.

например: 1010b = 10d, а не степень двойки

Таким образом, ваша функция должна перебрать все значение (набрав его, я бы предположил, чтобы получить длину в битах), затем &1 и суммировать результаты.

Когда это сделано, если > 1, то это NG, если вы считаете 0 как степень двух - это другое дело.

CPallini

Вы не ошибаетесь. Ни powoftwo является.
если вы отбросите все нули слева от первого сдвинув его вправо, то она является степенью двойки только в том случае, если она точно равна 1.

Рейтинг:
20

Patrice T

Цитата:
я пробовал отладку, но ничего не вышло

Эта цитата говорит о том, что вы не знаете, как использовать отладчик. отладчик только покажет вам, что делает ваш код, вы должны проверить переменные и проверить, все ли соответствует вашим ожиданиям.
Для быстрого старта вы можете найти tutos на youtube.

Эта строка находится в неправильном месте, потому что она будет пытаться выделить память независимо от ее значения. x Вы должны убедиться, что x является положительным перед выделением памяти.
int *numbers=malloc(sizeof(int)*x);


Когда вы не понимаете, что делает ваш код или почему он делает то, что делает, ответ таков: отладчик.
Используйте отладчик, чтобы увидеть, что делает ваш код. Просто установите точку останова и посмотрите, как работает ваш код, отладчик позволяет вам выполнять строки 1 на 1 и проверять переменные по мере их выполнения, это невероятный инструмент обучения.

Отладчик-Википедия, свободная энциклопедия[^]
Освоение отладки в Visual Studio 2010 - руководство для начинающих[^]
Базовая отладка с помощью Visual Studio 2010-YouTube[^]

Отладчик здесь для того, чтобы показать вам, что делает ваш код, и ваша задача-сравнить его с тем, что он должен делать.
В отладчике нет никакой магии, он не находит ошибок, он просто помогает вам. Когда код не делает того, что ожидается, вы близки к ошибке.