-1

I'm working on an assignment but I'm stuck. For some reason I can't get this outcome:

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

I have tried to solve this problem but I can't figure out where I went wrong. The following code is my attempt for this project. I feel that I'm nearing the end but I can't finish..

Here is my code:

#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;
}

My outcome for this code is:

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

I believe the problem lies in printNumberData() but I can't point where.

I hope someone can pitch in because any help is greatly appreciated.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
numbplum
  • 37
  • 1
  • 5
  • And what ARE you getting? – Mats Petersson Feb 10 '13 at 11:58
  • 2
    You need to give us something small to start with. A few dozen lines of code at most. The feeling one gets from the post as it stands now is that you've dumped the problem on us to solve. – John Zwinck Feb 10 '13 at 12:04
  • I'm sorry guys.. I forgot to post my outcome. I just posted it. @JohnZwinck I'm sure the code content is correct but I believe there is a small mistake that is causing wrong outcome. I just wanted to show my entire code and the desired outcome so that you guys could see what I'm trying to get at. Sorry if it was too much. – numbplum Feb 10 '13 at 12:11
  • 3
    Here's the thing. Nobody is likely to understand your code well enough to properly fix it until it is reduced to a more essential form which demonstrates the bug in isolation. Once that's done, it will probably be so simple to fix that you can do it yourself! – John Zwinck Feb 10 '13 at 12:15

2 Answers2

0

So, the only problem, as far as I see, is that your exponent isn't signed. You can fix that by changing tru_exp into a int8_t (or signed char). Or by simply sign-extending the number manually, e.g. if (tru_exp > 128) tru_exp -= 256;

Mats Petersson
  • 126,704
  • 14
  • 140
  • 227
0

You have a series of if statements which identify special cases (zeroes, infinities, NaNs), but you identify those after you've done some processing of 'normal' values. You should use an if / else if / else if chain instead, and deal with the special cases first, with the final else handling all the regular (normalized) numbers.

Here's some code based on what you provided, but the formatting and coding is considerably condensed. The main program here avoids input, and covers the gamut of values, I believe. When this is producing the correct data, you can futz with the formatting to suit the teacher's testing harness.

#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);
}

It produces one line of output per number:

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

If you read the Wikipedia page on Single-precision floating point format, you get an explanation of sorts about denormalized numbers having an adjusted exponent of -126 even though the value of the exponent bits is 0 and 0-127 is normally -127. Basically, it is simply stated by fiat that the exponent is -126 and underflow is occurring.

Other related pages do mention it, but somewhat more 'in passing':

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278