Как преобразовать int в двоичное строковое представление в C ++ - PullRequest
14 голосов
/ 23 мая 2010

У меня есть int, который я хочу сохранить как двоичное представление строки. Как это можно сделать?

Ответы [ 10 ]

38 голосов
/ 23 мая 2010

Попробуйте это:

#include <bitset>
#include <iostream>
int main()
{
    std::bitset<32>      x(23456);
    std::cout << x << "\n";


    // If you don't want a variable just create a temporary.
    std::cout << std::bitset<32>(23456) << "\n";
}
14 голосов
/ 23 мая 2010

У меня есть int, который я хочу сначала преобразовать в двоичное число.

Что именно это значит? Нет типа "двоичное число". Ну, int уже представлен в двоичном виде внутри, если вы не используете очень странный компьютер, но это деталь реализации - концептуально, это просто целое число.

Каждый раз, когда вы печатаете число на экране, оно должно быть преобразовано в строку символов. Так уж сложилось, что большинство систем ввода / вывода выбрали десятичное представление для этого процесса, чтобы людям было легче. Но нет ничего по сути десятичного в int.

В любом случае, чтобы сгенерировать базовое b представление целого числа x, просто следуйте этому алгоритму:

  1. инициализировать s пустой строкой

  2. m = x % b

  3. x = x / b

  4. Преобразовать m в цифру, d.

  5. Добавить d в s.

  6. Если x не равен нулю, перейдите к шагу 2.

  7. Реверс s

Шаг 4 прост, если b <= 10 и ваш компьютер использует кодировку символов, где цифры 0-9 являются смежными, потому что тогда это просто d = '0' + m. В противном случае вам понадобится справочная таблица.

Шаги 5 и 7 можно упростить, добавив d слева от s, если вы заранее знаете, сколько места вам понадобится, и начните с правого конца строки.

В случае b == 2 (например, двоичное представление) шаг 2 может быть упрощен до m = x & 1, а шаг 3 может быть упрощен до x = x >> 1.

Решение с reverse:

#include <string>
#include <algorithm>

std::string binary(unsigned x)
{
    std::string s;
    do
    {
        s.push_back('0' + (x & 1));
    } while (x >>= 1);
    std::reverse(s.begin(), s.end());
    return s;
}

Решение без reverse:

#include <string>

std::string binary(unsigned x)
{
    // Warning: this breaks for numbers with more than 64 bits
    char buffer[64];
    char* p = buffer + 64;
    do
    {
        *--p = '0' + (x & 1);
    } while (x >>= 1);
    return std::string(p, buffer + 64);
}
2 голосов
/ 23 мая 2010

http://snippets.dzone.com/posts/show/4716 или http://www.phanderson.com/printer/bin_disp.html - два хороших примера.

Основной принцип простого подхода:

  • Цикл, пока # не станет 0
  • & (поразрядно и) # с 1. Вывести результат (1 или 0) в конец строкового буфера.
  • Сдвиньте # на 1 бит, используя >>=.
  • Повтор цикла
  • Печать буфера обратной строки

Чтобы избежать обращения строки или необходимости ограничивать себя символами #, подходящими для длины строки буфера, вы можете:

  • Вычислить потолок (log2 (N)) - скажем, L
  • Маска вычисления = 2 ^ L
  • Цикл до маски == 0:
    • & (поразрядно и) маска с #. Выведите результат (1 или 0).
    • число & = (маска-1)
    • маска >> = 1 (разделить на 2)
1 голос
/ 15 мая 2011

И число с 100000 ..., затем 010000 ..., 0010000 ... и т. Д. Каждый раз, если результат равен 0, ставьте '0' в массиве char, в противном случае ставьте '1' .

int numberOfBits = sizeof(int) * 8;
char binary[numberOfBits + 1];
int decimal = 29;

for(int i = 0; i < numberOfBits; ++i) {
    if ((decimal & (0x80000000 >> i)) == 0) {
        binary[i] = '0';
    } else {
        binary[i] = '1';
    }
}
binary[numberOfBits] = '\0';
string binaryString(binary);
1 голос
/ 23 мая 2010

Полагаю, это связано с вашим другим вопросом о расширяемом хешировании.

Сначала определите несколько мнемоник для ваших битов:

const int FIRST_BIT = 0x1;
const int SECOND_BIT = 0x2;
const int THIRD_BIT = 0x4;

Тогда у вас есть номер, который вы хотите преобразовать в битовую строку:

int x = someValue;

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

if(x & FIRST_BIT)
{
    // The first bit is set.
}

И вы можете сохранить std :: string и добавить 1 к этой строке, если бит установлен, и вы добавите 0, если бит не установлен. В зависимости от того, в каком порядке вы хотите строку, вы можете начать с последнего бита и перейти к первому или только с первого до последнего.

Вы можете преобразовать это в цикл и использовать его для чисел произвольного размера, вычисляя указанные выше мнемонические биты, используя current_bit_value << = 1 после каждой итерации.

0 голосов
/ 31 января 2019

Это моя лучшая реализация преобразования целых чисел (любого типа) в std :: string.Вы можете удалить шаблон, если собираетесь использовать его только для одного целочисленного типа.Насколько я знаю, я думаю, что существует хороший баланс между безопасностью C ++ и загадочной природой C. Обязательно включите необходимые заголовки.

template<typename T>
std::string bstring(T n){
    std::string s;
    for(int m = sizeof(n) * 8;m--;){
            s.push_back('0'+((n >> m) & 1));
    }
    return s;
}

Используйте это так,

std::cout << bstring<size_t>(371) << '\n';

Это вывод на моем компьютере (он отличается на каждом компьютере),

0000000000000000000000000000000000000000000000000000000101110011

Обратите внимание, что копируется вся двоичная строка и, таким образом, дополняются нулями, что помогает представлять размер в битах.Таким образом, длина строки равна size_t в битах.

Давайте попробуем целое число со знаком (отрицательное число),

std::cout << bstring<signed int>(-1) << '\n';

Это вывод на моем компьютере (как указано, он отличается на каждом компьютере),

11111111111111111111111111111111

Обратите внимание, что теперь строка стала меньше, это доказывает, что sign int занимает меньше местачем size_t .Как вы можете видеть, мой компьютер использует метод дополнения 2 для представления целых чисел со знаком (отрицательные числа).Теперь вы можете понять, почему unsigned short(-1) > signed int(1)

Вот версия, созданная только для целых чисел со знаком , чтобы сделать эту функцию без шаблонов, т. Е. Использовать ее, если вы собираетесь преобразовать целые числа со знаком в строку.

std::string bstring(int n){
    std::string s;
    for(int m = sizeof(n) * 8;m--;){
            s.push_back('0'+((n >> m) & 1));
    }
    return s;
}
0 голосов
/ 20 ноября 2018

Решение без реверса, без дополнительной копии и с добавлением 0:

#include <iostream>
#include <string>

template <short WIDTH>
std::string binary( unsigned x )
{
    std::string buffer( WIDTH, '0' );
    char *p = &buffer[ WIDTH ];

    do {
        --p;
        if (x & 1) *p = '1';
    }
    while (x >>= 1);

    return buffer;
}

int main()
{
    std::cout << "'" << binary<32>(0xf0f0f0f0) << "'" << std::endl;
    return 0;
}
0 голосов
/ 12 января 2013

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

Пример:

std::cout << ConvertInteger<Uint32>::ToBinaryString(21);
// Displays  "10101"

auto x = ConvertInteger<Int8>::ToBinaryString(21, true);
std::cout << x << "\n"; // displays "00010101"

auto x = ConvertInteger<Uint8>::ToBinaryString(21, true, "0b");
std::cout << x << "\n"; // displays "0b00010101"
0 голосов
/ 23 мая 2010

Используйте функцию sprintf для сохранения форматированного вывода в строковой переменной, вместо printf для прямой печати.Однако обратите внимание, что эти функции работают только со строками C, а не со строками C ++.

0 голосов
/ 23 мая 2010

Прямой функции нет, вы можете просто пройтись по битам типа int (см. Подсказку >>) и вставить в строку «1» или «0».
Походит на стандартный вопрос типа интервью / домашней работы

...