3

このコードを C++ で実行します。

#include <iostream>
using namespace std;
int main()
{
    float f = 7.0;
    short s = *(short *)&f;
    cout << sizeof(float) << endl
         << sizeof(short) << endl
         << s << endl;
    return 0;
}

私は次のアウトポットを取得します:

4
2
0

しかし、スタンフォード大学で行われた講義で、Jerry Cain 教授は、アウト ポットが 0 ではないことは確かだと述べています。

レクチャーはここで好きになれます。彼は48分頃にそれを言います。

彼は間違っていますか、それともそれ以降の標準的な変更ですか? またはプラットフォーム間に違いはありますか?
g++ を使用してコードをコンパイルしています。

編集:次の講義で、彼は「ビッグ エンディアン」と「スモール エンディアン」について言及し、それらが結果に大きく影響すると述べています。

4

4 に答える 4

4
static void bitPrint(float f)
{
    assert(sizeof(int) == sizeof(float));
    int *data = reinterpret_cast<int*>(&f);
    for (int i = 0; i < sizeof(int) * 8; ++i)
    {
        int bit = (1 << i) & *data;
        if (bit) bit = 1;
        cout << bit;
    }
    cout << endl;
}

int main()
{
    float f = 7.0;
    bitPrint(f);
    return 0;
}

このプログラムは印刷します00000000000000000000011100000010

sizeof(short) == 2プラットフォーム上では、両方ともゼロである最初の2バイトを取得します。

タイプのサイズと場合によってはfloat実装(これについては不明)は実装定義であるため、プラットフォームごとに異なる出力が表示される可能性があることに注意してください。

于 2012-08-14T07:51:39.047 に答える
2

さて、見てみましょう。最初に float をメモリに書き込みます。これは 4 バイトを占有し、その値は 7 です。メモリ内の float は、「符号ビット -> 指数ビット -> 仮数ビット」のようになります。各部分に正確にいくつのビットがあるかはわかりませんが、おそらくプラットフォームによって異なります。

float の値は 7 であるため、右側の最下位ビットのみを占有します (ビッグエンディアンと仮定します)。

ポインターshortは float の先頭、つまり最上位ビットを指しています。値が 0 より大きいため、符号ビットは 0 です。float 値は右端にあるため、上位 2 バイトはゼロで埋められていると言えます。

ここで、 のサイズshortが 2 の場合、つまり、float の 4 バイトから 2 バイトだけを取得すると、0.

ただし、この結果はどちらかというと UB であり、プラットフォームやコンパイラなどによって異なる可能性があると思います。

于 2012-08-14T07:50:56.157 に答える
1

格納されていたものとは異なる型へのポインターを介してデータにアクセスすると、(いくつかの特殊なケースを除いて) 未定義の動作が発生します。

第一に、データの保存方法はプラットフォームに依存するため、システムが異なれば異なる値が返される可能性があります。第二に、コンパイラは、これを行うときに好きなことを行うことが許可されているため、期待する値すら表示しないコードを生成する可能性があります。 (厳密なエイリアス規則により、未定義の動作です)。

表示されている数値が有効である理由はおそらくあるとは言えますが、プラットフォームが期待どおりに機能することを明確に知っていない限り、それを信頼することはできません。標準では保証されていません。

于 2012-08-14T07:50:24.600 に答える
0

彼はそれがゼロではないことを「かなり」確信している、と彼ははっきりと言っている。

ただし、ショートの表現がビッグエンディアンまたはリトルエンディアンである可能性があることを考えると、私はそれほど確信が持てません。いずれにせよ、これは50分の講義の終わりにある使い捨てのラインなので、彼を少し許すことができます。次の講義で説明をつけて戻ってきたのかもしれません。

何が起こっているのかを理解するには、(少なくとも)バイトごとのレベルで基礎となるビットを調べる必要があります。

于 2012-08-14T07:53:04.007 に答える