-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_expint8_t(或signed char)来解决此问题。或者通过简单地手动签名扩展号码,例如if (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);
}

每个数字产生一行输出:

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

如果您阅读有关Single-precision floating point format的 Wikipedia 页面,您会得到关于调整指数为 -126 的非规范化数字的各种解释,即使指数位的值为 0 且 0-127 通常为 -127。基本上,法令只是简单地说明指数是-126并且正在发生下溢。

其他相关页面确实提到了它,但更多的是“顺便”:

于 2013-02-10T13:40:36.340 回答