-1

課題に取り組んでいますが、立ち往生しています。何らかの理由で、この結果を得ることができません:

byte order: little-endian

> FFFFFFFF
0xFFFFFFFF
signBit 1, expBits 255, fractBits 0x007FFFFF
QNaN

> 3
0x00000003
signBit 0, expBits   0, fractBits 0x00000003
denormalized: exp = -126

> DEADBEEF
0xDEADBEEF
signBit 1, expBits 189, fractBits 0x002DBEEF
normalized:   exp =  62

> deadbeef
0xDEADBEEF
signBit 1, expBits 189, fractBits 0x002DBEEF
normalized:   exp =  62

> 0
0x00000000
signBit 0, expBits   0, fractBits 0x00000000
+zero

この問題を解決しようとしましたが、どこが間違っていたのかわかりません。次のコードは、このプロジェクトに対する私の試みです。終わりに近づいてる気がするけど終わらない…

これが私のコードです:

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

static char *studentName = "name";

// report whether machine is big or small endian
void bigOrSmallEndian()
{
    int num = 1;
    if(*(char *)&num == 1)
    {
      printf("\nbyte order: little-endian\n\n");
   }
   else
  {
      printf("\nbyte order: big-endian\n\n");
  } 
}

// get next int (entered in hex) using scanf()
// returns 1 (success) or 0 (failure)
// if call succeeded, return int value via i pointer
int getNextHexInt(int *i)
{
    // replace this code with the call to scanf()
    //*i = 0;
    //return 1;
    scanf ("%x", i);
    return 1;
} 

// print requested data for the given number
void printNumberData(int i)
{
    //printf("%x %0#10x\n",i,*(int *)&i);
    int tru_exp =0;
    //int stored_exp;
    int negative;
    int exponent;
    int mantissa;

    printf("\n>");

    printf("\n0x%08X",i);

    negative = !!(i & 0x80000000);
    exponent = (i & 0x7f800000) >> 23;
    mantissa = (i & 0x007FFFFF);

    printf("\nsignBit %d, ", negative);
    printf("expbits %d, ", exponent);
    printf("fractbits 0x%08X", mantissa);
    // "%#010x, ", mantissa);

    if(exponent == 0)
    {
        if(mantissa != 0)
        {
            printf("\ndenormalized ");
        } 
    }
    else{
        printf("\nnormalized: ");
        tru_exp = exponent - 127;
        printf("exp = %d", tru_exp);
    }

    if(exponent == 0 && mantissa == 0 && negative == 1)
    {

        printf("\n-zero");

    }

    if(exponent ==0 && mantissa == 0 && negative == 0)
    {
        printf("\n+zero");
    }

    if(exponent == 255 && mantissa != 0 && negative == 1)
    {

        printf("\nQNaN");

    }

    if(exponent == 255 && mantissa != 0 && negative == 0)
    {

        printf("\nSNaN");

    }

    if(exponent == 0xff && mantissa == 0 && negative == 1)
    {
        printf("\n-infinity");
    }    

    if(exponent == 0xff && mantissa == 0 && negative == 0)
    {
        printf("\n+infinity");
    }

    printf("\n");
    while(i != 0)
        break;
}

// do not change this function in any way
int main(int argc, char **argv)
{
    int     i;                              // number currently being analyzed
    int     nValues;                        // number of values successfully parsed by    scanf

    printf("CS201 - A01p - %s\n\n", studentName);
    bigOrSmallEndian();
    for (;;) {
        if (argc == 1)                      // allow grading script to control ...
            printf("> ");                   // ... whether prompt character is printed
        nValues = getNextHexInt(&i);
        printf("0x%08X\n", i);
        if (! nValues) {                    // encountered bad input
            printf("bad input\n");
            while (getchar() != '\n') ;     // flush bad line from input buffer
            continue;
            }
        printNumberData(i);
        if (i == 0)
            break;
        }
    printf("\n");
    return 0;
}

このコードの私の結果は次のとおりです。

byte order: little-endian

> FFFFFFFF
0xFFFFFFFF

>
0xFFFFFFFF
signBit 1, expbits 255, fractbits 0x007FFFFF
normalized: exp = 128
QNaN
> 3
0x00000003

>
0x00000003
signBit 0, expbits 0, fractbits 0x00000003
denormalized
> DEADBEEF
0xDEADBEEF

>
0xDEADBEEF
signBit 1, expbits 189, fractbits 0x002DBEEF
normalized: exp = 62
> deadbeef
0xDEADBEEF

>
0xDEADBEEF
signBit 1, expbits 189, fractbits 0x002DBEEF
normalized: exp = 62
> 0
0x00000000

>
0x00000000
signBit 0, expbits 0, fractbits 0x00000000
+zero

問題はprintNumberData()どこにあると思いますが、どこにあるかはわかりません。

どんな助けでも大歓迎なので、誰かが参加できることを願っています。

4

2 に答える 2

0

したがって、私が見る限り、唯一の問題は、指数が署名されていないことです。(または)に変更tru_expすることで修正できます。または、単に数値を手動で符号拡張することによって、たとえばint8_tsigned charif (tru_exp > 128) tru_exp -= 256;

于 2013-02-10T13:40:12.237 に答える
0

if特殊なケース (ゼロ、無限大、NaN) を識別する一連のステートメントがありますが、「通常の」値の処理を行った後にそれらを識別します。if / else if / else if代わりにチェーンを使用し、特殊なケースを最初にelse処理し、最終的にすべての通常の (正規化された) 数値を処理する必要があります。

提供されたものに基づいたコードを次に示しますが、フォーマットとコーディングはかなり凝縮されています。ここでのメイン プログラムは入力を回避し、さまざまな値をカバーしていると思います。これで正しいデータが生成されたら、教師のテスト ハーネスに合わせてフォーマットを調整できます。

#include <stdio.h>

extern void printNumberData(int i);

void printNumberData(int i)
{
    int negative = (i & 0x80000000U) >> 31;
    int exponent = (i & 0x7F800000U) >> 23;
    int mantissa = (i & 0x007FFFFFU) >>  0;;

    printf("0x%08X sign %d, exponent %3d, fraction 0x%08X: ",
            i, negative, exponent, mantissa);

    if (exponent == 0x00 && mantissa == 0 && negative == 1)
        printf("-zero\n");
    else if (exponent == 0x00 && mantissa == 0 && negative == 0)
        printf("+zero\n");
    else if (exponent == 0xFF && mantissa != 0 && negative == 1)
        printf("QNaN\n");
    else if (exponent == 0xFF && mantissa != 0 && negative == 0)
        printf("SNaN\n");
    else if (exponent == 0xFF && mantissa == 0 && negative == 1)
        printf("-infinity\n");
    else if (exponent == 0xFF && mantissa == 0 && negative == 0)
        printf("+infinity\n");
    else if (exponent == 0)
        printf("denormalized: exp = -126\n");
    else
        printf("normalized:   exp = %4d\n", exponent - 127);
}

int main(void)
{
    printNumberData(0xFFFFFFFF);    /* QNan   */
    printNumberData(0x00000003);    /* Denorm */
    printNumberData(0x00800003);    /* Normal */
    printNumberData(0xDEADBEEF);    /* Normal */
    printNumberData(0x00000000);    /* +0     */
    printNumberData(0x80000000);    /* -0     */
    printNumberData(0xFF800000);    /* +Inf   */
    printNumberData(0x7F800000);    /* -Inf   */
    printNumberData(0xFF800001);    /* QNan   */
    printNumberData(0x7F800001);    /* SNan   */
    return(0);
}

数値ごとに 1 行の出力が生成されます。

0xFFFFFFFF sign 1, exponent 255, fraction 0x007FFFFF: QNaN
0x00000003 sign 0, exponent   0, fraction 0x00000003: denormalized: exp = -126
0x00800003 sign 0, exponent   1, fraction 0x00000003: normalized:   exp = -126
0xDEADBEEF sign 1, exponent 189, fraction 0x002DBEEF: normalized:   exp =   62
0x00000000 sign 0, exponent   0, fraction 0x00000000: +zero
0x80000000 sign 1, exponent   0, fraction 0x00000000: -zero
0xFF800000 sign 1, exponent 255, fraction 0x00000000: -infinity
0x7F800000 sign 0, exponent 255, fraction 0x00000000: +infinity
0xFF800001 sign 1, exponent 255, fraction 0x00000001: QNaN
0x7F800001 sign 0, exponent 255, fraction 0x00000001: SNaN

単精度浮動小数点形式に関するウィキペディアのページを読むと、指数ビットの値が 0 で 0 ~ 127 が通常 -127 であっても、調整された指数が -126 である非正規化数についての説明が得られます。基本的には、指数が-126でアンダーフローが発生していることを平易に表記しています。

他の関連ページでも言及されていますが、もう少し「通りすがり」です。

于 2013-02-10T13:40:36.340 に答える