views:

84

answers:

3

~ Please forgive me -

  • I had a previous post called IEEE - 754 - find signbit, exponent, frac, normalized, etc..

However, i had not registered my nic and i cant edit it. ( so the post is basically dead to me) Can someone delete it? My question is unanswered also. So i am posting this with different code.

  • i still need lots of help... so please dont treat this post as a duplicate...

I have found sign bit, exponent bit and mantissa..

What do i test to find normalized? if exp == 0?

what do i test for infinity? exp == 0xff and mantiassa == 0? does the sign have anything to do with it?

what do i test to find Zero? exp == 0 and mantissa == 0? does the sign have anything to do with it?

What do i test to find NAN? can someone please explain as simple as you can since i am just a beginner! Do i have to apply any more masks?

  • Is there a order in which i am suppose to accomplish what i want?

This is what i have so far.

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

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

    printf("IEEE- 754 \n");
    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;
}

...and this is my output - which is what i want:

IEEE - 754 

little-endian

>C0000000

0xc0000000
signBit 1,expbits 128,fractbits 0,
A: 

If you're using c99 try the function fpclassify, which will return an enumeration saying if the value is NAN, Infinity etc, and frexp which will split the value for you.

If you want to roll your own, remember that both infinities and zeros are signed. NaN's are defined by a specific bit pattern in the exponent I believe, the mantissa gives extra information in a nonstandard way.

From reading the draft standard:

  • If the exponent is zero and the mantissa is nonzero the value is denormal

  • If the exponent is zero and the mantissa is zero the value is (+/-) zero

  • If the exponent is the maximum and the mantissa is zero the value is (+/-) infinity

  • If the exponent is the maximum and the mantissa is nonzero the value is NAN

Scott Wales
reading the standard draft is nice. But, when we test for zero how do we know if its a plus or a minus? same with infinity?
Corey
@Corey It looks like Alok's answer shows the bits you need to check for a float. The value is `(-1)^[sign bit] * the rest`, so if the sign bit is set the value is negative. The sign bit used is the same for zero and infinity.
Scott Wales
+2  A: 

Why not verify it yourself?

#include <stdio.h>

void extract (float x) {
    union {
        float value;
        struct {
            unsigned int frac : 23;
            unsigned int exp  : 8;
            unsigned int sign : 1;
        } fields;
    } conv;
    conv.value = x;
    printf ("Value = %.3g,\tSign = %x,\tExp = %x,\tFrac = %x\n", x, conv.fields.sign, conv.fields.exp, conv.fields.frac);
}

int main() {
    extract (1.0f);     // normal number
    extract (1.0f/3.0f);    // normal number
    extract (0.0f);     // 0
    extract (-0.0f);    // -0
    extract (1.0f / 0.0f);  // inf
    extract (-1.0f / 0.0f); // -inf
    extract (0.0f / 0.0f);  // nan
    extract (1.e-40f);  // denormal
    extract (-1.e-42f); // denormal
    return 0;
}

Result:

Value = 1,  Sign = 0,   Exp = 7f,   Frac = 0
Value = 0.333,  Sign = 0,   Exp = 7d,   Frac = 2aaaab
Value = 0,  Sign = 0,   Exp = 0,    Frac = 0
Value = -0, Sign = 1,   Exp = 0,    Frac = 0
Value = inf,    Sign = 0,   Exp = ff,   Frac = 0
Value = -inf,   Sign = 1,   Exp = ff,   Frac = 0
Value = nan,    Sign = 0,   Exp = ff,   Frac = 400000
Value = 1e-40,  Sign = 0,   Exp = 0,    Frac = 116c2
Value = -1e-40, Sign = 1,   Exp = 0,    Frac = 116c2

Observation:

  • If exp = 0xff, it is either ±inf or nan.
    • If frac = 0, it is inf (+ or -).
    • If frac ≠ 0, it is nan (sign bit doesn't matter).
  • If exp = 0, it is either zero or denormal.
    • If frac = 0, it is zero (+ or -).
    • If frac ≠ 0, it is denormal (+ or -).

If you're using C, there is already isnan, isinf/isfinite, isnormal and signbit in <math.h> for these tests.

KennyTM
How do i check to se if the NAN is either SNAN or QNAN?
Corey
How do i know if its plus or minus?
Corey
Signalling/Quiet NaNs are implementation specific I believe, you'll have to look at the value of Frac. For plus/minus, look at the Sign value in the result.
Scott Wales
@Corey: (1) The sign bit tells you if it is + or -. (2) According to [IEEE 754](http://en.wikipedia.org/wiki/NaN), if the *top bit* (0x400000 here) of `frac` is set, it is a SNaN, otherwise a QNaN.
KennyTM
+1  A: 

In C99, you can use fpclassify() and signbit() macros from math.h (C99 draft, F.3):

The signbit macro and the fpclassify macro in <math.h>, used in conjunction with the number classification macros (FP_NAN, FP_INFINITE, FP_NORMAL, FP_SUBNORMAL, FP_ZERO), provide the facility of the class function recommended in the Appendix to IEC 60559 (except that the classification macros defined in 7.12.3 do not distinguish signaling from quiet NaNs).

To implement these tests on your own, you can use something like this (valid for float values, taken and modified from glibc sources):

int my_fpclassify(uint32_t x)
{
    x &= 0x7fffffff;
    if (x == 0)
        /* zero */
    else if (x < 0x800000)
        /* subnormal */
    else if (x > 0x7f800000)
        /* nan */
    else if (x == 0x7f800000)
        /* inf */
    else
        /* normal */
}

int my_signbit(uint32_t x)
{
    return x & 0x80000000;
}
Alok
what is x in this case? is it the floating point number?
Corey
x should be a float, it has been typecast to an int so that bit operations work.
Scott Wales
`x` is of type `uint32_t`. It has been obtained from a floating-point value, after fixing any endianness "issues".
Alok
How do i check to see if the NAN is either SNAN or QNAN?If Exponent=255 and Fraction bit is nonzero, then V=NaN ("Not a number")
Corey
@Corey, you should be able to figure it out yourself?!
Alok
well i wish i could. There is no good into on the web. if i could figure it out i wouldnt be on here =(
Corey