1

MBF を IEEE に変換するための以下のトピックを見つけました。

MBF シングルおよびダブルを IEEE に変換する

以下にマークされたコードの機能を説明できる人はいますか?

  1. Dim sign As Byte = mbf(6) And ToByte(&H80) ' AND (&H80) の理由は?

  2. Dim exp As Int16 = mbf(7) - 128S - 1S + 1023S 'なぜ 1152 (128+1+1023) なのですか?

  3. ieee(7) = ieee(7) または sign 'なぜ符号を ieee(7) に保存しないのですか?

  4. ieee(7) = ieee(7) または ToByte(exp >> 4 And &HFF) '4 をシフトする理由は何ですか?


Public Shared Function MTID(ByVal src() As Byte, ByVal startIndex As Integer) As Double
    Dim mbf(7) As Byte
    Dim ieee(7) As Byte

    Array.Copy(src, startIndex, mbf, 0, 8)

    If mbf(7) <> 0 Then
        Dim sign As Byte = mbf(6) And ToByte(&H80)
        Dim exp As Int16 = mbf(7) - 128S - 1S + 1023S

        ieee(7) = ieee(7) Or sign
        ieee(7) = ieee(7) Or ToByte(exp >> 4 And &HFF)
        ieee(6) = ieee(6) Or ToByte(exp << 4 And &HFF)

        For i As Integer = 6 To 1 Step -1
            mbf(i) <<= 1
            mbf(i) = mbf(i) Or mbf(i - 1) >> 7
        Next
        mbf(0) <<= 1

        For i As Integer = 6 To 1 Step -1
            ieee(i) = ieee(i) Or mbf(i) >> 4
            ieee(i - 1) = ieee(i - 1) Or mbf(i) << 4
        Next
        ieee(0) = ieee(0) Or mbf(0) >> 4
    End If

    Return BitConverter.ToDouble(ieee, 0)
End Function
4

1 に答える 1

6

IEEE754倍精度形式は、1ビットの符号、11ビットの指数、および52ビットの仮数で構成されています。

   7        6        5        4        3        2        1        0
seeeeeee eeeemmmm mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm 

エンディアンの変動により、左側の最上位バイトは実際ieee(7)には、右側の最下位バイトは次のようになります。ieee(0)これは以下の場合も同じですmbf()

指数は、(2 110 -1)までの値を提供します。そのうちのいくつかは、 (無限大)や(数値ではない)などの特別な値を表すために使用されます。2047+/-infnan

仮数ビットは、左から右へ、、などを1/2表し1/4ます1/8。数値を取得するには、n =(-1)s x 2 e- biasx1.mを計算します。

Microsoftのダブルバイナリ形式は次のとおりです。

   7        6        5        4        3        2        1        0
eeeeeeee smmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm

表示されるコードは、値をMBFからIEEE754倍精度形式に転送する(そしてわずかに変更する)だけです。

特定の質問に答えるには:

Dim sign As Byte = mbf(6) And ToByte(&H80)
'And&H80'の理由は何ですか?

16進数80(&H80)はバイナリパターン1000 0000です。

それでAND値をとると、&H80そのビットが設定されているかどうかが0わかります。

これは基本的に、番号の符号が何であったかを記録するだけであり、そのままでからmbf(6)に転送することができますieee(7)

Dim exp As Int16 = mbf(7) - 128S - 1S + 1023S
なぜ1152(128 + 1 + 1023)?

IEEE754の指数は、偏った指数です。つまり、格納されている値は0スルーである可能性255がありますが、それらによって表される実際の値は-128スルーである可能性があります127(現時点では特別な値は無視されます)。

これにより、非常に小さい値の場合は負の指数を、大きい値の場合は正の指数を使用できます。

MBF指数にもバイアスがかかっていますが128、シングルタイプとダブルタイプの両方でバイアスがかかっていますが、IEEE754倍精度指数の0ポイントは1023です。

余分な理由は-1、暗黙の行き先に関するMBFとIEEE754の違いによるもの1です。IEEE754はそれをバイナリポイントの前に置き、MBFの後に置きます。つまり、指数を1つ調整する必要があります。

ieee(7) = ieee(7) Or sign
サインをieee(7)に保存してみませんか?

ieee(7)その時点で明示的に設定されていないので、それは少し謎です。ieee()作成時にゼロに初期化されているとしか想定できません。そうしないと、ここでのほぼすべての転送操作が。で行われるため、問題が発生する可能性がありORます。

を使用する方が理にかなっているのは正しいですieee(7) = signOR指数ビットを組み合わせる実際のingは次の行にあります。

ieee(7) = ieee(7) Or ToByte(exp >> 4 And &HFF)
4シフトする理由は何ですか?

IEEE754の指数が2バイトを超えており、最も重要な指数の一部のみが必要なためです。指数の7ビットは最上位バイトに入り、残りの4ビットは次のバイトに入ります。

これは2行で処理されます。

ieee(7) = ieee(7) Or ToByte(exp >> 4 And &HFF) ' upper 7 bits '
ieee(6) = ieee(6) Or ToByte(exp << 4 And &HFF) ' lower 4 bits '

16ビット値が与えられると00000abcdefghijk、2つが計算されます。

>> 4 and &hff : 0abcdefg (s will go at the left)
<< 4 and &hff : hijk0000 (m will go at the right)
于 2010-09-22T03:25:20.670 に答える