20

2.25125 のような C++ の浮動小数点数と、浮動小数点数をメモリ (IEEE 754) に格納するために使用されるバイナリ値で満たされた int 配列を取得したいと考えています。

したがって、数値を取得して、浮動小数点数のバイナリ値を持つ int num[16] 配列になる可能性があります。num[0] は 1 num[1] は 1 num[2] は 0 num[3 ]は1などになります...

int を配列に入れるのは難しくありません。float のバイナリ値を取得するプロセスだけで行き詰っています。float 変数であるメモリ内のバイナリを読み取ることができますか? そうでない場合、どうすれば C++ でこれを行うことができますか?

編集: この方法で比較を行う理由は、C++ でビット単位の操作を行う方法を学びたいからです。

4

13 に答える 13

15
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ビットを左にシフトします。この演算子は、オペランドのビットごとの and&を計算します。

forループは float の 32 ビットごとに 1 回実行されます。毎回i、値を抽出したいビットの数になります。数値 and のビット単位の and を計算し1 << iます。

番号が 1001011 であると仮定します。i = 2

1<<i0000100に等しくなります

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

その場合i = 3

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

基本的に、結果はth ビットが元の数値iの th ビットに設定されたi数値になり、他のすべてのビットはゼロになります。結果はi、元の数値の th ビットが 0 であることを意味する 0 か、実際の数値のith ビットが に等しいことを意味する非ゼロのいずれかになり1ます。

于 2009-01-23T18:47:55.673 に答える
6

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;
}
于 2014-03-19T00:49:58.410 に答える
2

この回答 ( Floating Point to Binary Value(C++) ) のコメントを見ると、これを行う理由は、2 つの値のビットごとの比較を実行するためです。

#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";


}
于 2009-01-23T20:15:02.910 に答える
2

特定の浮動小数点表現が必要な場合は、ビットコピーではなく、float 自体から意味的に構築する必要があります。

c0x 標準: http://c0x.coding-guidelines.com/5.2.4.2.2.htmlは、浮動小数点数の形式を定義していません。

于 2009-01-23T18:49:18.010 に答える
2

float 変数であるメモリ内のバイナリを読み取ることができますか?

はい。それへのポインターを静的に int ポインターにキャストし、結果からビットを読み取ります。C++の IEEE 754float型は 32 ビットです。

于 2009-01-23T18:50:24.530 に答える
1

int ポインターを float ポインターにキャストすれば完了です。

(ただし、int 配列としては宣言しません。void* を使用して、メモリが他の値のダンプ グラウンドとして使用されていることを明確にします。)

ちなみに、浮動小数点数の配列を使用しないのはなぜですか?

于 2009-01-23T18:48:15.923 に答える
0

さて、C ++には、なんらかの問題なしにフロートを格納するための本当に安全な方法があるとは思いません。マシン間の移動に関しては、大容量のストレージを使用せずに効率的かつ簡単に保管できます。

非常に正確ですが、実際には非常識な値をサポートしません。どの場所でも最大7桁まで使用できますが、どちらの側でも7桁を超えることはできません。左側では、不正確な結果が表示されます。右側では、読み取り時にエラーが発生します。エラーを解決するには、書き込み中にエラーをスローするか、読み取りで「buffer [idx ++]&0x7」を実行して、0と7の境界を超えないようにします。「&0x7」は2の累乗から1を引いたものであるため、のみ機能することに注意してください。これは2^3- 1です。これは、0、1、3、7、15、31、63、127、255、511、1023などの値でのみ実行できます。

したがって、これを使用するかどうかはあなた次第です。必要なほとんどの値を取得するための安全な方法だと感じました。以下の例は、4バイト配列に変換される方法を示していますが、C++の場合はchar*になります。除算を実行したくない場合は、POWERS_OF_TEN配列を、代わりに小数と倍数の2次配列に変換できます。

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);
}
于 2012-12-28T05:20:43.827 に答える
-1

最も簡単な方法:

float myfloat;
file.read((char*)(&myfloat),sizeof(float));
于 2010-07-16T18:52:20.380 に答える