Аватар для Dendii
0 / 0 / 0
Регистрация: 15.08.2017
Сообщений: 9

Сколько установлено пар бит в числе

15.08.2017, 23:03. Показов 3157. Ответов 14
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Добрый день, учу си, попросили написать программу, которая будет выводить, сколько пар бит в целом числе.
Например есть число 57, которое выглядит как: 00111001, то есть две пары идущих друг за другом единиц.
Нужно вывести их. Мне предложили использовать сдвиг, но я не знаю, какой именно нужен алгоритм действий для результата.
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
15.08.2017, 23:03
Ответы с готовыми решениями:

Double to binary или как узнать сколько бит в числе?
Нужно узнать сколько бит в числе, оно может быть любым:1-целое положительное(напр 3),2-целое отрицательное(-3),3-число положительное с...

Замена бит в числе формата float
Доброго времени суток! Помогите, пожалуйста, с лабораторной работой. Задача следующая: Вводим с клавы десятичное число формата float....

Подсчитать число единичных бит в числе 161
Ребята памагите в решение задачки очь нужна ваша помощь на с не с++ Требуеться подчитать число эдиничных бит в числе 161 если...

14
1617 / 1182 / 553
Регистрация: 08.01.2012
Сообщений: 4,561
16.08.2017, 04:48
Цитата Сообщение от Dendii Посмотреть сообщение
Нужно вывести их
в каком виде?
Цитата Сообщение от Dendii Посмотреть сообщение
Например есть число
какого размера?
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
    unsigned char a=57;
    int l=sizeof(a)*8;
    char *mask=(char*)malloc(l+1);
 
    memset(mask,'0',l);
    mask[l-2]=mask[l-1]='1';
    mask[l]=0;
    for(; a; a>>=1)
    {
        if((a&3)==3) printf("%s\n",mask);
        memmove(mask,mask+1,l-1);
        mask[l-1]='0';
    }
    free(mask);
0
200 / 87 / 9
Регистрация: 15.11.2010
Сообщений: 472
16.08.2017, 09:58
Лучший ответ Сообщение было отмечено Dendii как решение

Решение

Dendii, а что, хорошая задачка. Учит низкоуровневой работе с числами и манипуляциям с битами. Такие задачи ещё на ассемблере интересно решать. Ты, правда, не очень хорошо сформулировал условие. Не очень понятно, что нужно выводить — сосчитанное количество пар соседних единичных бит, или нужно выводить сами пары, что вряд ли, ибо не имеет особого смысла. Наверное, всё-таки первое — т. е. нужно сосчитать, сколько раз единичные биты стоят друг с другом рядом во введённом числе, и вывести количество таких пар.

Написал маленькую программку, которая считывает целое число в обычном десятичном виде, выводит его же в двоичном представлении, а потом считает количество пар рядом стоящих друг за другом единичных бит и число этих пар также выводит в виде сообщения. Программка подробно прокомментирована, так что можно разобраться, что она делает. Единственный её недостаток, что для ввода числа она использует функцию scanf(), что не очень надёжно, поскольку эта функция плохо позволяет проанализировать ошибки ввода и не все их позволяет проанализировать. Лучше для этой цели использовать функцию fgets() в паре со strtol(). strtol() позволяет при желании проанализировать все ошибки при вводе целого и несоответствие введённой строки формату десятичного целого числа, но это важно при написании надёжных программ. Для учебной программы вполне хватит scanf(). Ну и гарантировать отсутствие ошибок в ней тоже не могу, хотя запускал — вроде работает.

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

Ну и, конечно, Керниган с Ритчи в помощь. В этом учебнике есть всё необходимое для начинающего сишного программиста.

И текст самой программы.


C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#include <stdio.h>
 
/* Msk - маска, содержащая 1 в своём старшем разряде и нули во всех остальных.
   Эта маска позволяет "вырезать" старший бит числа.
   Определяем её как макрос препроцессора.                                    */
 
#define Msk    (1 << sizeof(int) * 8 - 1)
 
 
int main()
{
 int n, N;     /* n - анализируемое число.
                  N - его копия, используемая для вспомогательных нужд.   */
 int i;
 int t;
 int p = 0;    /* Счётчик числа пар соседствующих единичных бит.  */
 int s = 0;    /* Переменная, хранящая состояние прошлого бита,
                  которое используется при анализе текущего бита. */
 int m;        /* Остаток от деления p на 10. Используется для получения
                  правильного окончания в выходном сообщении.             */
 
 
 /* Выводим подсказку-приглашение для ввода. */
 
 printf("Введите целое число:           ");
 
 
 /* Вводим анализируемое целое число в десятичной форме. */
 
 t = scanf("%d", &n);
 
 
 /* Анализируем возвращённое функцией scanf() значение, чтобы выявить ошибку
    при вводе числа. Если она действительна произошла, выводим сообщение
    в стандартный поток ошибок stderr и завершаем работу программы. */
 
 if(t==0 || t==EOF)
   {fprintf(stderr, "Данные введены с ошибкой. "
                    "Программа завершает свою работу.\n");
    return 1; }
 
 
 /* Выводим это же число в двоичном виде. Этого не требуется в задании,
    но это полезно нам, чтобы посмотреть, как выглядит число в двоичной форме.
    Т. к. в C нет спецификатора формата для двоичного представления чисел,
    позволяющего вывести целое число в двоичном виде с помощью функции
    printf(), пишем для этого маленький алгоритм c циклом и сдвигами в нём.   */
 
 printf("Двоичное представление числа:  ");
 
 N = n;        /* Работаем с копией N числа n. */
 
 for(i=0; i < sizeof(int) * 8; i++)
  {printf("%d", N & Msk ? 1 : 0);    /* Если в старшем бите числа N
                                        находится 1 - выводим 1,
                                        в противном случае выводим 0.  */
   N <<= 1;    /* Сдвигаем N на 1 бит влево. */
  }
 
 printf("\n");
 
 
 /* Подсчёт количества пар соседних единичных бит в числе n.
    Ведём его путём поразрядного сдвига числа n влево точно так же,
    как мы делали и при выводе этого числа в двоичном коде. */
 
  while(n)      /* Выполняем цикл, пока в числе есть хоть один единичный бит. */
{
 if(n & Msk)    /* Если в старшем разряде стоит 1,... */
   {if(s) p++;  /* Если в прошлый раз в старшем разряде была 1, увеличиваем
                   количество найденных пар соседних единичных бит на 1.    */
    s = 1;      /* Запоминаем, что в старшем разряде находилась 1,
                   для следующей итерации цикла, в которой будет
                   анализироваться следующий бит.                  */
   }
 else s = 0;    /* Если в старшем разряде находился 0, запоминаем это
                   для следующей итерации цикла. */
 n <<= 1;       /* Сдвигаем n на 1 двоичный разряд влево. */
}
 
 
 /* Выводим число p пар соседних единичных бит в числе n. Учитываем окончание
    в слове "пар(а)" в выходном сообщении. */
 
 printf("В числе встречается %d пар%s соседних единичных бит.\n", p,
        (m = p%10)>1 && m<5 ? "ы" : m==1 ? "a" : "");
 
 
 return 0; }

Та же программа, во вложении.
bitpairs.rar
2
 Аватар для Dendii
0 / 0 / 0
Регистрация: 15.08.2017
Сообщений: 9
16.08.2017, 13:05  [ТС]
JohnyWalker, огромное спасибо за помощь!
Более менее разобрался, укорачиваю комментарии и буду предъявлять преподу
0
200 / 87 / 9
Регистрация: 15.11.2010
Сообщений: 472
16.08.2017, 13:20
И отлично
0
153 / 148 / 66
Регистрация: 20.02.2014
Сообщений: 556
16.08.2017, 14:09
Цитата Сообщение от JohnyWalker Посмотреть сообщение
sizeof(int) * 8;
ну раз уже sizeof(int), то почему магические константы есть?
C
1
2
#include <limits.h>
sizeof(int) * CHAR_BIT
0
Модератор
Эксперт Pascal/DelphiЭксперт NIX
 Аватар для bormant
7816 / 4635 / 2837
Регистрация: 22.11.2013
Сообщений: 13,158
Записей в блоге: 1
21.08.2017, 18:04
JohnyWalker,
не проще было за (n-1) сдвиг проверить m&3==3?
C
1
2
3
4
5
6
7
8
unsigned int bitpairs(unsigned int n) {
    unsigned int r=0;
    for (int i=8*sizeof n-1; i>0; --i) {
        r += (n&3)==3;
        n >>= 1;
    }
    return r;
}
Добавлено через 6 минут
Или для знакового аргумента:
C
1
2
3
4
5
6
7
8
unsigned int bitpairs(int n) {
    unsigned int r=0, m=3;
    for (int i=8*sizeof n-1; i>0; --i) {
        r += (n&m)==m;
        m <<= 1;
    }
    return r;
}
Добавлено через 10 минут
Для беззнакового можно также
C
3
4
5
6
    while (n) {
        r += (n&3)==3;
        n >>= 1;
    }
или
C
3
4
5
6
    while (n>=3) {
        r += (n&3)==3;
        n >>= 1;
    }
3
Неэпический
 Аватар для Croessmah
18146 / 10730 / 2066
Регистрация: 27.09.2012
Сообщений: 27,030
Записей в блоге: 1
21.08.2017, 20:09
gcc:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <stdlib.h>
#include <inttypes.h>
#include <stdio.h>
 
#define ghb(n) (__builtin_clz(n))
#define shb(n) ((n) << ghb(n))
 
 
int main()
{
    uint32_t x = 2564554656u;
    uint32_t count = 0;
    if (~x) {
        while(x) {
            x = shb(x);
            uint32_t n = ghb(~x);
            if (n > 1) {
                count += (n - 1);
            }
            x <<= n;       
        }
    } else {
        count = 31;
    }
    printf("%" PRIu32, count);
}
http://rextester.com/SJEXIT43510
1
Модератор
Эксперт Pascal/DelphiЭксперт NIX
 Аватар для bormant
7816 / 4635 / 2837
Регистрация: 22.11.2013
Сообщений: 13,158
Записей в блоге: 1
22.08.2017, 10:54
Croessmah,
а Zero Flag после __builtin_clz(x) никак не проверить? Одним условием было бы меньше...
0
200 / 87 / 9
Регистрация: 15.11.2010
Сообщений: 472
24.08.2017, 03:58
Цитата Сообщение от bormant Посмотреть сообщение
JohnyWalker,
не проще было за (n-1) сдвиг проверить m&3==3?
bormant, я согласен, что так будет и быстрее с точки зрения скорости вычислений, и короче запись, и программа профессиональнее смотрится. Просто тему создал начинающий программист, и я подумал, что для него проще и понятнее будет то решение, которое я ему написал (ему в нём проще будет для начала разобраться). А дальше пусть он посмотрит и поймёт твоё решение, для него это тоже будет очень полезно. Кстати, мой подход тоже неплох, пусть не для анализа цепочки бит, а, положим, для анализа цепочки байт, допустим, если мы пишем лексический анализатор. Там уже за один раз попарно анализировать соседние байты вряд ли получится.
1
Модератор
Эксперт PythonЭксперт JavaЭксперт CЭксперт С++
 Аватар для easybudda
12843 / 7592 / 1766
Регистрация: 25.07.2009
Сообщений: 13,973
24.08.2017, 15:54
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <stdio.h>
 
unsigned char PAIRS[] = { 3, 6, 12, 24, 48, 96, 192 };
#define PAIRS_COUNT ( sizeof(PAIRS) / sizeof(PAIRS[0]) )
 
int main(void) {
    unsigned char n;
    
    while ( printf("Number[0 - 255]: ") && scanf("%hhu", &n) == 1 ) {
        int cnt = 0, i;
        
        for ( i = 0; i < PAIRS_COUNT; ++i )
            cnt += ( n & PAIRS[i] ) == PAIRS[i];
        
        printf("%d bit pairs.\n", cnt);
    }
    
    return 0;
}
0
Модератор
Эксперт Pascal/DelphiЭксперт NIX
 Аватар для bormant
7816 / 4635 / 2837
Регистрация: 22.11.2013
Сообщений: 13,158
Записей в блоге: 1
24.08.2017, 16:02
easybudda,
невыгодно.
Ради байта городить массив из 7 байт, и это при том, что ту же самую маску можно получить как m=3; m<<=1;
Да и на бОльшие размеры решение с маской легче масштабируется.
0
Неэпический
 Аватар для Croessmah
18146 / 10730 / 2066
Регистрация: 27.09.2012
Сообщений: 27,030
Записей в блоге: 1
24.08.2017, 17:55
Цитата Сообщение от bormant Посмотреть сообщение
а Zero Flag после __builtin_clz(x) никак не проверить?
Надо будет погуглить.
0
Модератор
Эксперт Pascal/DelphiЭксперт NIX
 Аватар для bormant
7816 / 4635 / 2837
Регистрация: 22.11.2013
Сообщений: 13,158
Записей в блоге: 1
24.08.2017, 18:02
Croessmah,
C
8
    int n = 0x80000000;
Видим же 0 пар, но выведет 1.
0
Неэпический
 Аватар для Croessmah
18146 / 10730 / 2066
Регистрация: 27.09.2012
Сообщений: 27,030
Записей в блоге: 1
24.08.2017, 18:04
Цитата Сообщение от bormant Посмотреть сообщение
Видим же 0 пар, но выведет 1.
Да я убрал код уже. Сам чухнул.
Для знаковых не подойдет,
а для беззнаковых чуть поменять код надо.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
24.08.2017, 18:04
Помогаю со студенческими работами здесь

Сколько бит займет такое определение
Добрый день. сколько бит займет такое определение { int tt=10; }

Определить сколько пар равных между собой чисел
a) Дано 3 числа. Определить сколько пар равных между собой чисел.

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

Сколько 0 содержится в числе?
Помогите пожалуйста написать прогу. Число должно быть любое,на выходе количество &quot;0&quot; в числе. Желательно неэффективным и...

Посчитать сколько установлено разного ПО в организации и у кого оно установлено
Добрый день! Простите за не информативный заголовок, не знаю как кратко сформулировать. Исходные данные: Имеется некий список...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Опции темы

Новые блоги и статьи
Символьное дифференцирование
igorrr37 13.02.2026
/ * Программа принимает математическое выражение в виде строки и выдаёт его производную в виде строки и вычисляет значение производной при заданном х Логарифм записывается как: (x-2)log(x^2+2) -. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL3_image
8Observer8 10.02.2026
Содержание блога Библиотека SDL3_image содержит инструменты для расширенной работы с изображениями. Пошагово создадим проект для загрузки изображения формата PNG с альфа-каналом (с прозрачным. . .
Установка Qt-версии Lazarus IDE в Debian Trixie Xfce
volvo 10.02.2026
В общем, достали меня глюки IDE Лазаруса, собранной с использованием набора виджетов Gtk2 (конкретно: если набирать текст в редакторе и вызвать подсказку через Ctrl+Space, то после закрытия окошка. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru