Самый простой способ:

у взять число с плавающей запятой в C ++, например 2.25125, и массив int, заполненный двоичным значением, которое используется для хранения числа с плавающей запятой в памяти (IEEE 754).

Таким образом, я могу взять число и получить массив типа int num [16] с двоичным значением типа float: num [0] будет 1 num [1] будет 1 num [2] будет 0 num [3 ] будет 1 и так далее ...

Поместить int в массив не сложно, я просто застрял в процессе получения двоичного значения с плавающей точкой. Можете ли вы просто прочитать двоичный файл в памяти, что переменная с плавающей точкой? Если нет, то как я могу сделать это в C ++?

РЕДАКТИРОВАТЬ: причина для проведения сравнения таким образом, что я хочу научиться делать побитовые операции в C ++.

 Arkadiy23 янв. 2009 г., 20:30
Из любопытства - зачем вам одно целое число на бит?

Ответы на вопрос(11)

другой подход, используя STL

#include <iostream>
#include <bitset>

using namespace std;
int main()
{
    float f=4.5f;
    cout<<bitset<sizeof f*8>(*(long unsigned int*)(&f))<<endl;
    return 0;
}

запятой в массив целых чисел:

unsigned int bits[sizeof (float) * CHAR_BIT];
unsigned char const *c = static_cast<unsigned char const*>(
    static_cast<void const*>(&my_float)
);

for(size_t i = 0; i < sizeof(float) * CHAR_BIT; i++) {
    int bitnr = i % CHAR_BIT;
    bits[i] = (*c >> bitnr) & 1;
    if(bitnr == CHAR_BIT-1)
        c++;
}

// the bits are now stored in "bits". one bit in one integer.

Кстати, если вы просто хотите сравнить биты (как вы комментируете другой ответ), используйтеmemcmp:

memcmp(&float1, &float2, sizeof (float));

я не верю, что в C ++ есть какой-то реальный безопасный способ хранения чисел без каких-либо проблем. Когда дело доходит до перемещения между машинами, оно эффективно и легко хранится без использования большой емкости.

Это очень точно, но это не будет поддерживать действительно безумные ценности. Вы можете иметь до 7 цифр в любом месте, но вы не можете превышать 7 цифр с обеих сторон. Слева вы получите неточные результаты. Справа вы получите ошибку во время чтения. Чтобы устранить ошибку, вы можете выдать ошибку во время записи или выполнить «buffer [idx ++] & 0x7» для чтения, чтобы предотвратить выход за пределы 0 и 7 границ. Имейте в виду, что «& 0x7» работает только потому, что это степень 2 минус один. Что составляет 2 ^ 3 - 1. Вы можете сделать это только с этими значениями, например, 0, 1, 3, 7, 15, 31, 63, 127, 255, 511, 1023 и т. Д.

Так что решать вам, хотите ли вы использовать это или нет. Я чувствовал, что это был безопасный способ получить большинство ценностей, которые вам когда-либо понадобятся. В приведенном ниже примере показано, как он преобразуется в 4-байтовый массив, но для C ++ это будет символ *. Если вы не хотите выполнять деление, вы можете преобразовать массив POWERS_OF_TEN во вторичный массив с десятичными и кратными взамен.

const float CacheReader::POWERS_OF_TEN[] = 
{
    1.0F, 10.0F, 100.0F, 1000.0F, 10000.0F, 100000.0F, 1000000.0F, 10000000.0F
};

float CacheReader::readFloat(void)
{
    int flags = readUnsignedByte();
    int value = readUnsignedTriByte();
    if (flags & 0x1)
        value = -value;
    return value / POWERS_OF_TEN[(flags >> 1) & 0x7];
}

unsigned __int32 CacheReader::readUnsignedTriByte(void)
{
    return (readUnsignedByte() << 16) | (readUnsignedByte() << 8) | (readUnsignedByte());
}

unsigned __int8 CacheReader::readUnsignedByte(void)
{
    return buffer[reader_position] & 0xFF;
}

void CacheReader::writeFloat(float data)
{
    int exponent = -1;
    float ceiling = 0.0F;

    for ( ; ++exponent < 8; )
    {
        ceiling = (POWERS_OF_TEN[exponent] * data);
        if (ceiling == (int)ceiling)
            break;
    }

    exponent = exponent << 0x1;
    int ceil = (int)ceiling;
    if (ceil < 0)
    {
        exponent |= 0x1;
        ceil = -ceil;
    }
    buffer[writer_position++] = (signed __int16)(exponent);
    buffer[writer_position++] = (signed __int16)(ceil >> 16);
    buffer[writer_position++] = (signed __int16)(ceil >> 8);
    buffer[writer_position++] = (signed __int16)(ceil);
}

(Хотя я бы не объявил его как массив int. Я бы использовал void *, чтобы прояснить, что память используется в качестве полигона для других значений.)

Кстати, почему бы вам просто не использовать массив с плавающей точкой?

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

стандарт c0x:http://c0x.coding-guidelines.com/5.2.4.2.2.html не определяет формат чисел с плавающей точкой.

int fl = *(int*)&floatVar; //assuming sizeof(int) = sizeof(float)

int binaryRepresentation[sizeof(float) * 8];

for (int i = 0; i < sizeof(float) * 8; ++i)
    binaryRepresentation[i] = ((1 << i) & fl) != 0 ? 1 : 0;
объяснение

(1 << i) меняет значение1, i биты влево.& Оператор вычисляетпоразрядно и операндов.

for Цикл запускается один раз для каждого из 32 битов с плавающей точкой. Каждый раз,i будет номером бита, из которого мы хотим извлечь значение. Мы вычисляем побитовое и число и1 << i:

Предположим, что число: 1001011, иi = 2

1<<i будет равен 0000100

  10001011
& 00000100
==========
  00000000

еслиi = 3 тогда:

  10001011
& 00001000
==========
  00001000

В основном результатом будет число сiбит установлен вiй бит исходного числа, а все остальные биты равны нулю. Результат будет либо ноль, что означаетiБит в исходном числе был нулевым или отличным от нуля, что означаетiбит равен1.

 Mehrdad Afshari23 янв. 2009 г., 20:16
@ Кристоф: я сомневаюсь в этом. Посмотри на вопрос. Он говорит, что хочет получить двоичное представление типа float в массиве int.
 Christoph23 янв. 2009 г., 20:03
Это не то, что он хочет: двоичное представление должно быть массивом размераsizeof(float) * CHAR_BIT (-1)
 Christoph23 янв. 2009 г., 20:23
Он хочет, чтобы массив int содержал битовую комбинацию, т. Е. Одно целое для каждого бита, поэтому его размер должен быть числом битов в переменной с плавающей запятой, т. Е. 32 (он неправильно предположил, что значение с плавающей запятой занимает 16 бит ...)
 Konrad Rudolph23 янв. 2009 г., 22:10
Mehrdad, любая причина для использования довольно устаревшего броска в стиле C вместо рекомендованногоreinterpret_cast Вот? В значительной степени все согласны с тем, что приведение в стиле C никогда не должно использоваться, особенно в «учебном» примере.
 Mehrdad Afshari23 янв. 2009 г., 22:37
@Konrad, это короче :) Единственной целью моего ответа была строка в цикле for. Я не хотел загромождать ответ ненужными лучшими практиками.

Самый простой способ:

float myfloat;
file.read((char*)(&myfloat),sizeof(float));

Смотря на комментарии в этом ответе (С плавающей запятой к двоичному значению (C ++)) причина сделать это состоит в том, чтобы выполнить побитовое сравнение двух значений.

#include <iostream>

int main()
{
    union Flip
    {
         float input;   // assumes sizeof(float) == sizeof(int)
         int   output;
    };

    Flip    data1;
    Flip    data2;
    Flip    data3;

    data1.input = 2.25125;
    data2.input = 2.25126;
    data3.input = 2.25125;

    bool    test12  = data1.output ^ data2.output;
    bool    test13  = data1.output ^ data3.output;
    bool    test23  = data2.output ^ data3.output;

    std::cout << "T1(" << test12 << ") T2(" << test13 << ") T3(" << test23 << ")\n";


}

что переменная с плавающей точкой?

Да. Static приводит указатель на него к указателю на int и считывает биты из результата. IEEE 754float тип в C ++ составляет 32 бита.

с плавающей запятой и переберите биты беззнакового длинного значения, как уже описано в других ответах.

Это исключит операторы приведения.

Решение Вопроса

Используйте union и bitset:

#include <iostream>
#include <bitset>

int main()
{
    union
    {
         float input;   // assumes sizeof(float) == sizeof(int)
         int   output;
    }    data;

    data.input = 2.25125;

    std::bitset<sizeof(float) * CHAR_BIT>   bits(data.output);


    std::cout << bits << std::endl;

    // or

    std::cout << "BIT 4: " << bits[4] << std::endl;
    std::cout << "BIT 7: " << bits[7] << std::endl;
}

Это может быть не массив, но вы можете получить доступ к битам с помощью оператора [], как если бы вы использовали массив.

Выход

$ ./bits
01000000000100000001010001111011
BIT 4: 1
BIT 7: 0
 underscore_d15 нояб. 2015 г., 00:35
@deft_code не только это, но также ложно, что "ieee754 с плавающей запятой всегда 32 бит". Перечитайте стандарт и отметьте 3 типа, указанные там, а затем подумайте об удалении вашего комментария.
 deft_code11 февр. 2009 г., 18:50
Число с плавающей запятой ieee754 всегда 32-битное, в c ++ предполагается использовать ieee754 для типов с плавающей запятой. Long также считается 32-битным. Измените объединение, чтобы использовать long вместо int, и вы получите действительно переносимый код.
 Martin York04 мая 2013 г., 02:22
@deft_code: C ++ являетсяНЕ Предполагается использовать ieee754 (это может быть). ДлинныйНЕ указано как 32 бита (должно быть не менее 32). Это никогда не будет переносимым, поскольку присваивание одному полю в объединении и чтение из другого - неопределенное поведение. Если я ошибаюсь по поводу любого из вышеперечисленных, пожалуйста, дайте мне знать пункт в стандартах C ++, где он определен, потому что простой поиск показал, что оба утверждения неверны.

Ваш ответ на вопрос