Как вывести число в двоичном виде cи
Перейти к содержимому

Как вывести число в двоичном виде cи

  • автор:

Битовые операции

Данный урок курса можно считать факультативным, т. е. необязательным. Для освоения темы этого урока вам потребуется знание о двоичной системе счисления, навыки перевода чисел из одной системы счисления в другую, а также вы должны иметь представление о том, что такое битовые (они же поразрядные) операции. С последним можно познакомиться по вот этой лекции.

В языке программирования C существуют следующие поразрядные операции: & (И), | (ИЛИ), ^ (исключающее ИЛИ), > (сдвиг вправо), ~ (поразрядное дополнение до единицы). Рассмотрим на примерах, как они работают, но перед этим уделим внимание выводу в языке C чисел в отличных от десятичной системах счисления.

В С можно присваивать целочисленные значения в десятичной, восьмеричной и шестнадцатеричной системах счисления. Для того, чтобы присвоить переменной число в восьмеричной системе счисления, перед ним надо написать 0 (ноль), в шестнадцатеричной — 0x (ноль и икс), например:

int a, b; a = 077; // восьмеричное число b = 0x1F; // шестнадцатеричное число

Любые целые числа можно выводить на экран в десятичном, восьмеричном и шестнадцатеричном представлении. Пример кода для вывода определенных ранее двух переменных в различных системаъ счисления:

printf("%d %o %x %X\n", a,a,a,a); printf("%d %o %x %X\n", b,b,b,b);

В результате на экране вы увидите:

63 77 3f 3F 31 37 1f 1F

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

0 000
1 001
2 010
3 011
4 100
5 101
6 110
7 111

Теперь допустим, что у нас есть восьмеричное число 037. По таблице легко понять, что в двоичном выражении оно будет выглядеть как 011 111.

  1. Как будут выглядеть восьмеричные числа 04271 и 03566 в двоичном представлении.
  2. Составьте на бумаге таблицу соответствия шестнадцатеричный цифр двоичным числам. Переведите числа 7D, FFFF, 2C9 в двоичную систему счисления.

Итак, если бы мы при работе с поразрядными операциями использовали десятичные числа, то чтобы оценить результат нам бы каждый раз приходилось переводить десятичное число в двоичную систему счисления, что относительно трудоемко. Если же человек видит, например, восьмеричное число, то он может представить как оно выглядит в двоичном представлении, помня или держа перед глазами таблицу соответствия чисел. Например, как только мы видим 017, то можем представить в уме, как последние четыре бита ячейки памяти забиты единицами.

Теперь вернемся к поразрядным операциям и протестируем каждую из них. Для этого напишем небольшую программу:

int a, b; a = 017; b = 036; printf("0%o & 0%o = 0%o\n", a, b, a & b); printf("0%o | 0%o = 0%o\n", a, b, a | b); printf("0%o ^ 0%o = 0%o\n", a, b, a ^ b); printf("0%o \n", a, a  2); printf("0%o >> 2 = 0%o\n", a, a >> 2); printf("~0%o = 0%o\n", a, ~a);

Результат ее работы будет выглядеть так:

017 & 036 = 016 017 | 036 = 037 017 ^ 036 = 021 017 > 2 = 03 ~017 = 037777777760

Этот результат будет проще понять с помощью рисунка:

Результат побитовых операций

В последнем случае получилось такое большое число потому, что под форматы вывода целых чисел ( %d, %o, %X ) выделяется по 4 байта.

  • Используя шестнадцатеричные числа, напишите аналогичную приведенной выше программу. Объясните результат.
  • Попробуйте составлять сложные битовые операции (в несколько действий) и оценивать их результат.

Теперь рассмотрим пример использования битовых операций. Допустим, у нас есть массив, требуется снять с него «маску», которая бы отражала, в какой позиции стоят отрицательные, а в какой положительные элементы. Пусть единица в бите обозначает соответствующий ей положительный элемент массива, а ноль — отрицательный. Другими словами, если у нас есть массив , то его «битовая маска» будет выглядеть как 101110, или в восьмеричном представлении как 056. Составим алгоритм решения этой задачи:

  1. Будем считать, что массив состоит не более чем из 32 элементов. Поэтому для хранения его «маски» достаточно переменной типа int . Назовем ее mask и присвоим значение 0.
  2. Перебрать элементы массива в цикле for . Если встречается положительный элемент, то установить соответствующий ему бит значения mask в 1.
  3. Вывести значение переменной mask на экран в виде восьмеричного числа.

Вроде бы все просто, но как установить в единицу определенный бит числа? Существует закономерность соответствия степеней двойки и двоичного представления числа:
2 0 = 0000 0001
2 1 = 0000 0010
2 2 = 0000 0100
2 3 = 0000 1000
2 4 = 0001 0000
и т.д. Теперь если применить к mask побитовую операцию | (ИЛИ), а в качестве второго операнда использовать определенную степень двойки, то один бит будет установлен в 1. Например:
(0) 0000 0000 | (2 5 ) 0010 0000 = 0010 0000
(32) 0010 0000 | (2 7 ) 1000 0000 = 1010 0000

При переборе первый элемент массива имеет индекс 0, но соответствующий ему бит в maskдолжен стоять впереди остальных. Если известно общее количество элементов массива (N), то можно определить степень двойки по формуле N — i — 1 . Действительно, имея третий положительный элемент массива из 10 элементов, следует установить в единицу восьмой с конца бит, а это значит надо использовать вторым операндом битового ИЛИ 27, а 7 как раз будет 10(N) — 2(i) — 1.

Другая проблема — как в языке C возвести число в степень. Понятно, что можно написать свой код, но скорее всего в стандартной библиотеке уже есть подобная функция. С помощью заголовочного файла math.h можно подключить библиотеку с математическими функциями. Среди них есть функция pow() , которая принимает два числа и возвращает результат возведения первого числа в степень, выраженную вторым числом. Однако результат возвращается в виде вещественного числа, а нам требуется целое. Как быть? В языке программирования С есть операции приведения типов, которые меняют тип значения с одного на другой. Например, чтобы преобразовать значение вещественной переменной a в целое, следует написать (int) a .
Вот как может выглядеть вышеописанная программа:

#include #include #define N 12 int main() { int nums[N] = {7, 3, 9, -5, -3, 2, 1, 0, 16, -4, 2, 0}; int mask = 0, i; for (i=0; i  N; i++) if (nums[i] >= 0) mask = mask|(int)pow(2,N-i-1); printf("%o\n", mask); }

Напишите предыдущую программу. Оцените как она работает 1 . Подумайте над тем, как вывести на экран двоичное представление восьмеричного числа. Попробуйте реализовать это.

1 Если у вас не получается скомпилировать программу, добавьте в конце вызова gcc опцию -lm (например, gcc -o bits bits.c -lm ).

Курс с решением части задач:
pdf-версия

Вывести число в двоичном виде

Сложить двоичные числа и вывести ответ в двоичном и десятичном виде
Даны два неотрицательных числа в двоичной системе счисления. Необходимо сложить их и вывести ответ.

Вывести 1 байтовое целое число без знака в двоичном коде
1. вывести 1 байтовое целое число без знака в 2-ом коде а) с использованием операции деления, б) с.

Вывести число в двоичном виде
0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 Есть число.

Число в двоичном виде в обратном порядке.
Дано натуральное число N. Выведите его представление в двоичном виде в обратном порядке.

Эксперт PythonЭксперт JavaЭксперт CЭксперт С++

12243 / 7373 / 1734

Регистрация: 25.07.2009

Сообщений: 13,521

kruss802, а Вы бы по форуму поискали. Здесь таких задачек, как у дурака махорки. Один из вариантов:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
#include void bin_print(unsigned n) { if ( n ) { bin_print(n >> 1); printf("%u", n & 1); } } int main(void) { unsigned n; while ( printf("\nNumber: ") && scanf("%u", &n) == 1 && n ) bin_print(n); return 0; }
[andrew@easybook numbers]$ gcc -Wall bin_print.c [andrew@easybook numbers]$ ./a.out Number: 5 101 Number: 127 1111111 Number: 256 100000000 Number: 257 100000001 Number: q [andrew@easybook numbers]$

87844 / 49110 / 22898

Вывод двоичного числа в СИ

@avp без преобразования возможно вывести в этом чудесном языке? или нужно каждый символ обрабатывать и выводить?

12 фев 2019 в 17:46
0010 не является двоичным числом в синтаксисе Си
12 фев 2019 в 17:46
printf(«%s», «0010»); , не?
12 фев 2019 в 17:49

@Qada: Для утилитарных целей место двоичного вывода в языке С занял шестнадцатеричный вывод. Если вам все это нужно «для дела», то пользуйтесь шестнадцатеричным. Если же вам нужен именно двоичный (ибо «задание такое»), то да — «каждый символ обрабатывать и выводить».

12 фев 2019 в 18:09

1 ответ 1

Сортировка: Сброс на вариант по умолчанию

Вы даете printf восьмеричное число 10 и просите напечатать его как десятичное. Вам выводится 8 — вы ждали чего-то другого?

Не существует спецификации формата для вывода двоичных чисел, поэтому их надо выводить вручную. В качестве примера:

// Вывод байта в двоичном виде typedef unsigned char byte; int main() < byte b = 93; // Или любое другое for (int i = 0; i < 8; i++) < printf("%c", (b & 0x80) ? '1' : '0'); b printf("\n"); return 0; > 

Отслеживать
ответ дан 12 фев 2019 в 18:44
4,884 8 8 золотых знаков 15 15 серебряных знаков 29 29 бронзовых знаков

    Важное на Мете
Похожие

Подписаться на ленту

Лента вопроса

Для подписки на ленту скопируйте и вставьте эту ссылку в вашу программу для чтения RSS.

Дизайн сайта / логотип © 2023 Stack Exchange Inc; пользовательские материалы лицензированы в соответствии с CC BY-SA . rev 2023.10.27.43697

Нажимая «Принять все файлы cookie» вы соглашаетесь, что Stack Exchange может хранить файлы cookie на вашем устройстве и раскрывать информацию в соответствии с нашей Политикой в отношении файлов cookie.

Вывод числа в двоичном представлении

Интересно, как можно вывести число в двоичном представлении? Есть какие-то методы о которых я не знаю или это нужно делать в ручную через оператора if или case?

Лучшие ответы ( 1 )
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
Ответы с готовыми решениями:

Вывод числа в двоичном представлении
Собственно, нужно вывести целое десятичное число в двоичном виде. Это все) Так как форматированного.

Посчитать количество едениц в двоичном представлении числа. Найти ошибку в коде
#include <string.h> #include <stdio.h> #include <stdlib.h> void main() < union

Вывести числа из диапазона от n до m, в двоичном представлении которых ровно k разрядов установленных в «01»
Доброго времени суток. Есть задача:Вывести числа из диапазона от n до m , в двоичном представлении.

Заменить шестнадцатеричную цифру на количество единиц, имеющихся в ее двоичном представлении
Дано короткое целое неотрицательное число. Заменить каждую входящую в его состав шестнадцатеричную.

Нарушитель
8920 / 4799 / 1111
Регистрация: 12.03.2015
Сообщений: 22,627

ЦитатаСообщение от r00kzy_ Посмотреть сообщение

как можно вывести число в двоичном представлении?
например, вот так:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
char* void2bin(void* data, size_t size) { char* dest = new char[1 + 8 * size]; char* ptr = dest; uint8_t* b = (uint8_t*)(data) + size - 1; for (size_t bit = 8 * size; bit--; ptr++) { *ptr = (*b & (1  (bit & 7))) ? '1' : '0'; if (!(bit % 8)) b--; } dest[8 * size] = 0; return dest; }

Регистрация: 05.09.2019
Сообщений: 51

Не дано мне понимать С++, к сожалению
Буду очень признателен, если получится этот код перевести на C# или Си, или Java потому что С++ очень сложный для понимания тем, кто не знает синтаксиса)
Это как я понимаю метод, который принимает data — число и size — размер бит?

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
char* void2bin(void* data, size_t size) { char* dest = new char[1 + 8 * size]; //Динамический массив символов равный 1+8*?(размер бит) char* ptr = dest; // uint8_t* b = (uint8_t*)(data) + size - 1; //Создал беззнаковую переменную b? for (size_t bit = 8 * size; bit--; ptr++) //Происхождение переменной bit берёт своё начало от size как я понимаю?) { *ptr = (*b & (1  (bit & 7))) ? '1' : '0'; if (!(bit % 8)) b--; } dest[8 * size] = 0; return dest; }

Добавлено через 4 минуты
Копипаст со стэка, вроде как работает с 1 байтом.

1 2 3 4 5 6 7 8 9 10 11
typedef unsigned char byte; int main() { byte b = 93; // Или любое другое for (int i = 0; i  8; i++) { printf("%c", (b & 0x80) ? '1' : '0'); b  1; } printf("\n"); return 0; }

Нарушитель
8920 / 4799 / 1111
Регистрация: 12.03.2015
Сообщений: 22,627

Лучший ответ

Сообщение было отмечено r00kzy_ как решение

Решение

ЦитатаСообщение от r00kzy_ Посмотреть сообщение

Не дано мне понимать С++, к сожалению

ничего страшного. Все работы хороши, выбирай на вкус. ©

ЦитатаСообщение от r00kzy_ Посмотреть сообщение

этот код перевести на C#

В сишарпе не шарю.

ЦитатаСообщение от r00kzy_ Посмотреть сообщение

Достаточно заменить new char[1 + 8 * size] на (char*)malloc(sizeof(char) * (1 + 8 * size)) . В любом случае память надо будет отдать через delete[] или free() соответственно.

ЦитатаСообщение от r00kzy_ Посмотреть сообщение

Это как я понимаю метод, который принимает data — число и size — размер бит?

Нет. data — это указатель на любые данные, а size — это размер этих данных (в байтах).
Пример использования (перевод числа с плав. точкой в двоичный вид):

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
/* Verevkin, CodeBlocks, кодировка файла: UTF-8 BOM */ // d:\Soft\CodeBlocks\share\CodeBlocks\templates\wizard\console\cpp\main.cpp // #include раскомментарить, если надо system() и т.п. #include #include #include #include #include char* void2bin(void* data, size_t size) { char* dest = new char[1 + 8 * size]; char* ptr = dest; uint8_t* b = (uint8_t*)(data) + size - 1; for (size_t bit = 8 * size; bit--; ptr++) { *ptr = (*b & (1  (bit & 7))) ? '1' : '0'; if (!(bit % 8)) b--; } dest[8 * size] = 0; return dest; } int main(int argc, char** argv) { system("chcp 65001 & cls"); char key; double F; uint64_t* L = (uint64_t*)&F; do { printf("\n? F = "); scanf("%lf", &F); char* bin_str = void2bin(&F, sizeof(F)); printf("$ F = %g --> 0x%I64X --> : %s\n", F, *L, bin_str); delete []bin_str; printf(" >> Ещё разок? [y/n]: "); key = getch(); } while (key != 'n' && key != 'N' ); printf("\n >> Нажми что-нибудь для выхода. "); getch(); return 0; }

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *