Преобразование целого числа в двоичную строку с использованием itoa в C / C ++ - PullRequest
3 голосов
/ 14 марта 2012

Могу ли я использовать itoa() для преобразования long long int в двоичную строку? Я видел различные примеры для преобразования int в двоичный файл, используя itoa. Есть ли риск переполнения или потери точности, если я использую long long int.

Edit- Спасибо всем за ответ. Я достиг того, что я пытался сделать. itoa () не был достаточно полезен, так как не поддерживает long long int. Более того, я не могу использовать itoa () в gcc, так как это не стандартная библиотечная функция.

Ответы [ 4 ]

5 голосов
/ 14 марта 2012

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

Примерно так:

std::string convert_to_binary_string(const unsigned long long int value,
                                     bool skip_leading_zeroes = false)
{
    std::string str;
    bool found_first_one = false;
    const int bits = sizeof(unsigned long long) * 8;  // Number of bits in the type

    for (int current_bit = bits - 1; current_bit >= 0; current_bit--)
    {
        if ((value & (1ULL << current_bit)) != 0)
        {
            if (!found_first_one)
                found_first_one = true;
            str += '1';
        }
        else
        {
            if (!skip_leading_zeroes || found_first_one)
                str += '0';
        }
    }

    return str;
}

Редактировать:

Более общий способ сделать это можно сделать с помощью шаблонов:

#include <type_traits>
#include <cassert>

template<typename T>
std::string convert_to_binary_string(const T value, bool skip_leading_zeroes = false)
{
    // Make sure the type is an integer
    static_assert(std::is_integral<T>::value, "Not integral type");

    std::string str;
    bool found_first_one = false;
    const int bits = sizeof(T) * 8;  // Number of bits in the type

    for (int current_bit = bits - 1; current_bit >= 0; current_bit--)
    {
        if ((value & (1ULL << current_bit)) != 0)
        {
            if (!found_first_one)
                found_first_one = true;
            str += '1';
        }
        else
        {
            if (!skip_leading_zeroes || found_first_one)
                str += '0';
        }
    }

    return str;
}

Примечание: Оба static_assert и std::is_integral является частью C ++ 11, но поддерживается как в Visual C ++ 2010, так и в GCC как минимум с 4.4.5.

3 голосов
/ 14 марта 2012

Да, вы можете. Как вы показали себя , itoa можно вызвать с помощью базы 2, что означает двоичный код.

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

int main()
{
    int i;
    char str[33];

    i = 37; /* Just some number. */
    itoa (i, str, 2);
    printf("binary: %s\n", str);

    return 0;
}

Кроме того, да, будет усечение, если вы используете целочисленный тип, больший, чем int, поскольку itoa () принимает в качестве значения только простое значение "int". long long на вашем компиляторе, вероятно, 64-битный, в то время как int, вероятно, 32-битный, поэтому компилятор перед преобразованием усечет 64-битное значение до 32-битного.

1 голос
/ 14 марта 2012

Ваша формулировка немного сбивает с толку, обычно, если вы укажете «десятичное число», я буду считать, что это означает: «число, представленное в виде строки десятичных цифр», в то время как вы, кажется, имеете в виду «целое число».

и с «двоичным» я бы взял это, чтобы означать: «число, представленное в байтах - как непосредственно используемое процессором».

лучший способ сформулировать вашу тему: преобразовать 64-битное целое в строку двоичных цифр.

некоторые системы имеют функцию _i64toa.

0 голосов
/ 08 декабря 2014

Стандартный способ преобразования в long long: strtoull() и std::strtoull() для C и C ++ соответственно

Пример cppreference

#include <iostream>
#include <cstdlib>

int main()
{
    const char* begin = "10 200000000000000000000000000000 30 40";
    char *end;
    for (unsigned long i = std::strtoul(begin, &end, 10);
         begin != end;
         i = std::strtoul(begin, &end, 10))
    {
        begin = end;
        if (errno == ERANGE){
            std::cout << "range error\n";
            errno = 0;
        }    
        std::cout << i << '\n';
    }
}
...