Thread: IEEE 754 - signbit, expBits, fractbits,normalized

  1. #1
    Registered User
    Join Date
    Sep 2006
    Location
    vancouver wa
    Posts
    221

    IEEE 754 - signbit, expBits, fractbits,normalized

    I am taking in a 8 digit hexadecimal number as an IEEE 754 bit floating point number
    and i want to print information about that number( signbit, expbits, fractbits, normalized,
    denormalized, infinity, zero, NAN) floating point should be a single.


    I read up on bit shifting, and i think this is how i am suppose to do it?. however, i am not 100% sure. I understand that the sign bit is found in the left most position of the number. which indicates positive or negative. How much do i shift it to find each? do i just keep shifting it to find each one? Can someone explain how i am to find each one?

    would i shift by 1 to find the signbit?
    would i shift by 8 to get the exponent?
    would i shift by 23 to get the frac?

    if so how do i test it after i shift?

    this is what i have so far

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    int main(int argc, char *argv[])
    {
    
    
    	int SwapTest[2] = { 1, 0 };
    	int HexNumber;
    
    	printf("Hex IEEE - 754\n");
    
    
    	if( *(short *) SwapTest == 1 )
    	{
    		//little endian
    		printf("\nbyte order: little-endian\n");
    	}
    	else
    	{
    		printf("byte order: big-endian\n");
    	}
    	printf("\n>");
    	scanf("%x", &HexNumber);
    	printf("\n%#x",HexNumber);
    
    
    
    
    	return 0;
    }
    My input would be
    40000000

    and i get
    0x40000000
    which is what i want..
    Last edited by mrsirpoopsalot; 01-11-2010 at 03:09 PM.

  2. #2
    Registered User
    Join Date
    Apr 2006
    Posts
    2,149
    Yeah, shifting the correct number of units right, and ANDing with the correct number of set bits is how you would normally do this. For example:
    Code:
    int eg = 0xEA;//1110 1010
    (eg>>3)&0x7;
    This will get you the 4th through 6th least significant digits, here resulting in the number 5.
    Last edited by King Mir; 01-11-2010 at 04:43 PM.
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

  3. #3
    Registered User
    Join Date
    Sep 2006
    Location
    vancouver wa
    Posts
    221
    I am still lost.

  4. #4
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Quote Originally Posted by mrsirpoopsalot View Post
    I am taking in a 8 digit hexadecimal number as an IEEE 754 bit floating point number
    No you're not. You're just reading in an int as hex. There is no 'float' or 'double' anywhere in that program.

    Surely you actually mean to input a float?
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  5. #5
    Registered User
    Join Date
    Apr 2006
    Posts
    2,149
    No, I think he wants to input as hex, and output what each part of the floating point variable would be if he reinterpret cast it to float.

    That doesn't require having float anywhere in the program, since getting the parts of the number requires reinterpreting back to an integer type, and the two casts cancel each other out.

    Here's spelling it out a bit more:
    Code:
    int eg = 0xEA;//1110 1010 
    //desired number in green
    //olive shows where 3 comes from
    // 0x7 is 111b, which is the bitmask to show three digits.
    (eg>>3)&0x7;
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

  6. #6
    Registered User
    Join Date
    Jul 2009
    Posts
    36
    I've written an article that might help you, although it's not exactly what you want. I use doubles, though I list modifications to make it work for floats. Also, you should be able to modify it easily enough to use a hex representation: Displaying the Raw Fields of a Floating-Point Number - Exploring Binary

  7. #7
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Quote Originally Posted by King Mir View Post
    No, I think he wants to input as hex, and output what each part of the floating point variable would be if he reinterpret cast it to float.

    That doesn't require having float anywhere in the program, since getting the parts of the number requires reinterpreting back to an integer type, and the two casts cancel each other out.
    That'll make it really hard to ensure that the code is correct if the data is never viewed in float form at any point. The code could just as easily be disecting an arbitraryly made up floating point format.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  8. #8
    Registered User
    Join Date
    Sep 2006
    Location
    vancouver wa
    Posts
    221
    King mir is correct -
    No, I think he wants to input as hex, and output what each part of the floating point variable would be if he reinterpret cast it to float.
    I am understanding this more. The IEEE single precision floating point standard representation requires a 32 bit word, which may be represented as numbered from 0 to 31, from 0 on the RIGHT to 31 on the LEFT.. The first bit is the sign bit, the next eight bits are the exponent bits, and the final 23 bits are the fraction.

    Therefore, to extract the sign bit we use the appropriate mask and shift by 31 to get the sign at the end?

    In addition to get the value of the exponent. since, its 8 bits in length, we shift by 31 - 8(23) to shift it to the end?

    If true then the mantissa requires no shifting? Also, to extract the value we use the mask. This part confuses me.

    I think Bit masks are used to access specific bits in a byte of data?
    if so, How do we come up with that hex number(bit mask)?
    How do we know how many digits to show?

    @DoctorBinary - I love your webpage..
    Last edited by mrsirpoopsalot; 01-13-2010 at 04:06 PM.

  9. #9
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Okay I get that you want to input data as hex. But how the heck do you know what float number the random hex that you enter corresponds to?
    How do you know that you typed in the correct data?
    How will you even know that your program is producing the correct result?

    DoctorBinary: Why don't use a compile-time assert to check (and self-document) your compile-time assumption? Then you don't have any runtime penalty and there is no reason to take it out. Heck you don't even have to run the program to check the assertion! In MSVC, just use C_ASSERT for this.
    Last edited by iMalc; 01-14-2010 at 12:59 AM.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  10. #10
    Registered User
    Join Date
    Jul 2009
    Posts
    36
    Quote Originally Posted by mrsirpoopsalot View Post
    @DoctorBinary - I love your webpage..
    Thanks.

    The bitmasks are just the hex equivalent of binary. So 0x7FF equals 011111111111 in binary; that is, a leading 0 and eleven 1 bits. You set the bits to 1 or 0 depending on how you are masking -- with "and" or "or". (See Mask (computing) - Wikipedia, the free encyclopedia, for example, to learn more about bitmasks).

    Quote Originally Posted by iMalc View Post
    DoctorBinary: Why don't use a compile-time assert to check (and self-document) your compile-time assumption? Then you don't have any runtime penalty and there is no reason to take it out. Heck you don't even have to run the program to check the assertion! In MSVC, just use C_ASSERT for this.
    Yes, that would be cleaner. Can you give me an example that is compiler independent?

  11. #11
    Registered User
    Join Date
    Sep 2006
    Location
    vancouver wa
    Posts
    221
    can someone help me?
    I am still stuck. I have found the sign bit, exponent bit, and mantissa. how can i tell if its normalized or denormalized? What about infinity? zero? or NAN
    please i want to learn but i dont know what to do. Can someone give me clear instructions? or some working code?

    This is what i have so far..

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

    Here is my output which is what i want..
    Code:
    
    
    little-endian
    
    >c0000000
    
    0xc0000000
    signBit 1,expbits 128,fractbits 0,
    Last edited by mrsirpoopsalot; 01-19-2010 at 01:13 AM.

  12. #12
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    fpclasify will tell you the answer to those things, but you'll need to cast it to a float for that, which is the third time I find myself saying that.

    For the last time, reinterpret (i.e. cast) it as a float, to ensure that anything you're doing is actually correct at all.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  13. #13
    Registered User
    Join Date
    Sep 2006
    Location
    vancouver wa
    Posts
    221
    iMalc,

    For the last time, reinterpret (i.e. cast) it as a float, to ensure that anything you're doing is actually correct at all.
    My code should accept user input in the form of 8 hexadecimal digits.
    My code will interpret those 8 digits as an IEEE 754 32-bit floating point
    number and will print out information about that number.

    I want to use scanf to get the user input. My code should accept input with
    or without "0x" in front of it (scanf does this).



    Is this what you want me to do?

    Code:
    float HexNumber;
    
    scanf("%x", &HexNumber);

  14. #14
    Registered User
    Join Date
    Apr 2006
    Posts
    2,149
    Quote Originally Posted by mrsirpoopsalot View Post
    can someone help me?
    I am still stuck. I have found the sign bit, exponent bit, and mantissa. how can i tell if its normalized or denormalized? What about infinity? zero? or NAN
    Single precision floating-point format - Wikipedia, the free encyclopedia

    It explains the criteria for being normalized, denormalized, infinity, zero, -0, or NaN.

    You would have to check which criteria fit.
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

  15. #15
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Quote Originally Posted by mrsirpoopsalot View Post
    My code should accept user input in the form of 8 hexadecimal digits.
    My code will interpret those 8 digits as an IEEE 754 32-bit floating point
    number and will print out information about that number.

    I want to use scanf to get the user input. My code should accept input with
    or without "0x" in front of it (scanf does this).
    Your code is just saying "if this were the bits of a float, then the float would have e.g. an exponent of ...".
    Is this what you want me to do?

    Code:
    float HexNumber;
    
    scanf("%x", &HexNumber);
    Not really. You don't have to change how you input the value. You already know how to treat the bytes as a different type because you did it here::
    Code:
       unsigned char *c = (unsigned char*)(&a);
    It's pretty similar to treat an int as a float:
    Code:
       float f = *(float*)(&HexNumber);
    Now you can do:
    Code:
    #include <float.h>
    
    ...
    
        if (_fpclass(f) == _FPCLASS_PD)
            printf("positive denormal!\n");
        if (_fpclass(f) == _FPCLASS_PINF)
            printf("positive infinity!\n");
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

Popular pages Recent additions subscribe to a feed