2

IEEE 754 ビット浮動小数点数として 8 桁の 16 進数を取り込んでおり、その数値 (signbit、expbits、fractbits、正規化、非正規化、無限大、ゼロ、NAN) 浮動小数点数に関する情報を出力したいのですが、単一である必要があります。

私はビットシフトについて読みましたが、これが私がそれを行う方法だと思いますか?. ただし、100% 確実ではありません。符号ビットが数字の一番左の位置にあることを理解しています。正または負を示します。それぞれを見つけるにはどれだけシフトしますか?それぞれを見つけるためにシフトし続けるだけですか?誰かが私がそれぞれを見つける方法を説明できますか?

符号ビットを見つけるために 1 シフトしますか? 指数を取得するために 8 シフトしますか? frac を得るために 23 シフトしますか?

符号ビットはゼロでなければなりません

expbits は 128 にする必要があります

fracbits は 0x00000000 である必要があると思います...

もしそうなら、シフト後にどのようにテストしますか?

これは私がこれまでに持っているものです

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{

    short wordOrder = 0x0100;

int HexNumber;

printf("Hex IEEE - 754\n");



    if(wordOrder == 0x0100)
    {
    printf("\nbyte order: big-endian\n");
    }
    else
    {
    printf("byte order: little-endian\n");
    }

printf("\n>");
scanf("%x", &HexNumber);
printf("\n%#x",HexNumber);




return 0;
    }

私が望む方法に関する私の入力(scanf)..

>40000000
0x40000000

それは何をしているのか..

4

7 に答える 7

13

単精度数の場合、上位ビットは符号、次の8ビットは指数、残りの23ビットは仮数です。それで...

bool negative = !!(HexNumber & 0x80000000);
int exponent = (HexNumber & 0x7f800000) >> 23;
int mantissa = (HexNumber & 0x007FFFFF);

指数が255の場合、仮数がゼロであるかどうかに応じて、数値は+-無限大またはNaNのいずれかになります(0は無限大を意味します)。指数がゼロの場合、その数は+-ゼロ(仮数がゼロの場合)であるか、仮数が実際の正規化されていない小数値です。

指数がそれ以外の場合、小数部の上部に1ビットが非表示になり、24ビットになります。この場合、実際の指数は、指数から127を引いて、2の指数の累乗である-127から+127の範囲になるように計算できます。

于 2010-01-11T21:39:56.557 に答える
1

コードが正しいかどうかを確認するには、コンバーター アプレット http://www.h-schmidt.net/FloatApplet/IEEE754.htmlを使用します。

アプレットがいくつかの値をチェックするのに役立つことがわかりました。

于 2010-01-11T21:56:53.993 に答える
1

& は、2 つの値の間でビットごとの演算を行います。値の 1 つが定数である場合、いくつかの便利なプロパティがあります。

  A | B | A & B 
 ---+---+------- 
  0 | 0 | 0 
  0 | 1 | 0 
 ---+---+------- 
  1 | 0 | 0 
  1 | 1 | 1 

真理値表でわかるように、最初の 2 行は、A = 0 の場合、A & B = 0 であることを示しています。したがって、ある位置のマスクにゼロを配置すると、そのビットをクリアする効果があります。

最後の 2 行は、A = 1 の場合、A & B = B であることを示しています。したがって、ある位置のマスクに 1 を入れると、そのビットを渡す効果があります。

したがって、定数マスクを使用して、既知のフィールドの外側のビットをクリアできます。

OR (|) と XOR (^) を使用して同じ演習を行い、| で使用するマスクを結論付けることができます。マスクが 1 である値のビットを設定する効果があります。^ は、マスクが 1 である値のビットをトグルする効果があります。

/* コメントへの返信 */

これは指数ビットではなく、8 ビット長の指数フィールドです。したがって、次のようにマスクを作成するとします。

0111 1111 1000 0000 0000 0000 0000 0000  (mask === 0x7F800000)
1011 1010 0101 0110 0110 1010 1001 1010  (value)
-------------------------------------------------
0011 1010 0000 0000 0000 0000 0000 0000   (result)

ここで、この操作から残っているのは、指数フィールドを構成するビット (つまり、01110100) だけであることがわかります。フィールドの値を知りたい場合は、必要な量だけ結果を右にシフトする必要があります。必要な量は、(一般に)フィールドの最下位ビットのゼロインデックス付きビット位置です。指数フィールドの場合、必要なシフト量は 23 です。

ちなみに、右にシフトするときは注意が必要です。マスクの最上位ビットが 0 であることはわかっているので、ここでは問題ありませんが、そうでない場合は、右にシフトする前に結果を符号なしの値にキャストするのが賢明でしょう。そうしないと、符号が拡張されます。

int8_t exponent = ((uint32_t) (value & 0x7F800000)) >> 23; 
// the cast is not necessary in this case because the mask has a 0 in the msb

符号ビットを抽出したい場合は、次のキャスト重要になります。

int8_t sign = ((uint32_t) (value & 0x80000000)) >> 31; 

(符号ビットを抽出するために 8 だけシフトする必要があるという考えをどこで得たのかわかりません)

于 2010-01-12T20:11:34.113 に答える
1

すでに検討しているちょっとした工夫に加えて、浮動小数点数を分析してスケーリングできるライブラリ関数がいくつかあります。

floatまたはdoubleが手元にある場合は、 を使用std::frexp()して仮数 (または仮数) と指数を決定できます。指数は整数になりますが、仮数は 0.5 から 1 または 0 の間の実数になります。

于 2010-01-11T22:12:24.060 に答える
0

コードの改訂:

#include <stdio.h>
 #include <stdlib.h>

int main(int argc, char *argv[])
{


int HexNumber;




int a = 0x12345678;
unsigned char *c = (unsigned char*)(&a);
if (*c == 0x78)
{
  printf("\nlittle-endian\n");
}
else
{
  printf("\nbig-endian\n");
}

printf("\n>");
scanf("%x", &HexNumber);
printf("\n%#x",HexNumber);


 bool negative = !!(HexNumber & 0x80000000);
 int exponent = (HexNumber & 0x7f800000) >> 23;
 int mantissa = (HexNumber & 0x007FFFFF);


 printf("\nsignBit %d,", negative);
 printf("expbits %d,", exponent);
 printf("fractbits %#x,", mantissa);




return 0;
}
于 2010-01-19T04:07:26.877 に答える
0

icelated 質問:

誰かがここで何が起こっているのか説明できますか? &numbers はどこから来るのでしょうか?

& 演算子は、ビットごとの AND 演算子です。16 進数はビット マスクです。適切なマスクを使用して & 演算子を適用すると、関心のあるビットを分離できます。

于 2010-01-12T00:45:12.360 に答える
0

@vicatcu、またはこれが他の誰か

氷で冷やした..

IEEE 単精度浮動小数点標準表現には、左から右に 0 から 31 までの番号が付けられた 32 ビット ワードが必要です。最初のビットは符号ビット、次の 8 ビットは指数ビット、最後の 23 ビットは小数です。

したがって、符号ビットを抽出するには、適切なマスクを使用し、31 シフトして最後に符号を取得しますか? 指数の値を取得することに加えて。長さは 8 ビットなので、31 - 8(23) をシフトして最後にシフトしますか? true の場合、仮数はシフトを必要としませんか? また、値を抽出するためにマスクを使用します。この部分は私を混乱させます。マスクは16進数に相当すると思います。どうやってその 16 進数を思いつくのでしょうか? 例: int exponent = (HexNumber & 0x7f800000) ありがとうございます - 私はこれを取得していると思います....

于 2010-01-12T23:42:08.100 に答える