4

履歴バイナリ データ ファイルを読み取る方法を理解しようとしています。古い 32 ビット Solaris システムからのものだと思います。32 ビット浮動小数点数 (IEEE 浮動小数点数ではない) が含まれていると思われるファイルのセクションを見ています。フォーマットは次のようになります (16 進ダンプとして):

xx41 xxxx
xx42 xxxx

これらの位置の 41 と 42 は、浮動小数点数を通じて一貫して表示されます。申し訳ありませんが、これに追加する追加情報がありません。私の質問の最初の部分は、これはどのような形式ですか? 最初の部分に直接答えられない場合は、考えられる可能性のリストが役立ちます。最後に、これがどのような形式であるかを判断する方法を提案してください。ご意見ありがとうございます。

4

2 に答える 2

4

これは PDP-11 形式でしょうか? 私にとっての見所は、2 番目のバイトがほぼ一定であることです。これは、浮動小数点形式の指数が最初のバイトではなく 2 番目のバイトで終わることを示唆しています (ビッグエンディアンのマシンに期待されるように) または最後 (リトル エンディアン マシンの場合)。PDP-11 は、浮動小数点数と整数のバイト順がおかしなことで有名です。この浮動小数点形式のページの下部にある資料を参照してください。

との値は4142おおよそ単位の大きさの正の値と一致しているように見えます: PDP-11 形式の指数バイアス128は符号と指数の最上位 7 ビット。これにより、2 番目のバイトの偏りのない指数は41、8 番目の指数ビット (最初のバイトの MSB として表示されるはずです) に応じて 2 または 3 になります。

PDP-11 形式の簡単な説明については、このページも参照してください。

[編集] 4 バイト文字列が PDP-11 形式の浮動小数点数を表すと仮定して、記述した形式の 4 バイト文字列から Python 浮動小数点数に変換する Python コードを次に示します。

import struct

def pdp_to_float(xs):
    """Convert a 4-byte PDP-11 single-precision float to a Python float."""

    ordered_bytes = ''.join(xs[i] for i in [1, 0, 3, 2])
    n = struct.unpack('>I', ordered_bytes)[0]

    fraction = n & 0x007fffff
    exponent = (n & 0x7f800000) >> 23
    sign = (n & 0x80000000) >> 31

    hidden = 1 if exponent != 0 else 0
    return (-1)**sign * 2**(exponent-128) * (hidden + fraction / 2.0**23)

例:

>>> pdp_to_float('\x00\x00\x00\x00')
0.0
>>> pdp_to_float('\x23\x41\x01\x00')
5.093750476837158
>>> pdp_to_float('\x00\x42\x00\x00')
16.0
于 2012-06-07T13:28:29.590 に答える
3

記述されたデータは通常の IEEE 754 形式と一致しており、ビッグ エンディアンの順序で格納され、リトル エンディアンのダンプ プログラムによって一度に 2 バイトずつ表示されます。

間隔 [8, 128) の 32 ビット float は、0x41 または 0x42 の最初のバイトを持ちます。そのような数値、おそらく 0x41010203 を考えてみましょう。ビッグ エンドが最初に格納され、4 バイト 0x41、0x01、0x02、および 0x03 としてメモリに表示されます。ダンプ プログラムが 16 バイトの整数を読み取る場合、リトル エンドが最初で、0x0141 と 0x0302 を読み取って表示します。

于 2012-06-07T23:32:59.943 に答える