Question

I have written this program:

#include <stdio.h>
#include <stdint.h>
/*
 * See also : http://class.ece.iastate.edu/arun/CprE281_F05/ieee754/ie5.html
 */

union FloatingPointSinglePrecisionIEEE754 {
    struct {
        unsigned int mantissa : 23;
        unsigned int exponent : 8;
        unsigned int sign : 1;
    } raw;
    float f;
} fnumber;

union FloatingPointDoublePrecisionIEEE754 {
    struct {
        uint64_t mantissa : 52;
        unsigned int exponent : 11;
        unsigned int sign : 1;
    } raw;
    double d;
} dnumber;



int main() {

    printf("sign\texponent\tmantissa\n");

    fnumber.f = -6.8;
    printf("%x\t%x\t\t%x\n",
            fnumber.raw.sign,
            fnumber.raw.exponent,
            fnumber.raw.mantissa); 


    dnumber.d = -6.8;
    printf("%x\t%x\t\t%x\n",
            dnumber.raw.sign,
            dnumber.raw.exponent,
            dnumber.raw.mantissa); 


return 0;
}

For single precison I have get the true output but for double-precison the program is fail. any one could help me how can I write convertor fo Double-Precison?

Was it helpful?

Solution

The program below seems to work for me. I get:

sign    exponent    mantissa
1   81      59999a
1   401     b333333333333

The two changes I made are using the proper C99 format PRIx64 in printf() (See this wikipedia page for information about these formats) and using the same base type for the bit-fields in the struct in union FloatingPointDoublePrecisionIEEE754. Bit-fields are notoriously under-specified but using different base types may cause the compiler to start a new word, not what you want here.

#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
/*
 * See also : http://class.ece.iastate.edu/arun/CprE281_F05/ieee754/ie5.html
 */

union FloatingPointSinglePrecisionIEEE754 {
    struct {
        unsigned int mantissa : 23;
        unsigned int exponent : 8;
        unsigned int sign : 1;
    } raw;
    float f;
} fnumber;

union FloatingPointDoublePrecisionIEEE754 {
    struct {
        uint64_t mantissa : 52;
        uint64_t exponent : 11;
        uint64_t sign : 1;
    } raw;
    double d;
} dnumber;



int main() {

    printf("sign\texponent\tmantissa\n");

    fnumber.f = -6.8;
    printf("%x\t%x\t\t%x\n",
            fnumber.raw.sign,
            fnumber.raw.exponent,
            fnumber.raw.mantissa); 


    dnumber.d = -6.8;
    printf("%x\t%x\t\t%" PRIx64 "\n",
            dnumber.raw.sign,
            dnumber.raw.exponent,
       (uint64_t)dnumber.raw.mantissa); 


return 0;
}

OTHER TIPS

It could be that your printf is the one that fails as you are trying to output a 64-bit unsigned int with a simple %x formatter. Use a %xl for a "long" unsigned int:

dnumber.d = -6.8;
printf("%x\t%x\t\t%xl\n",  // note the %xl format specifier for the mantissa
        dnumber.raw.sign,
        dnumber.raw.exponent,
        dnumber.raw.mantissa); 

See printf reference

python code is simple as follows:

def hb(a):
    ab = bin(int(a[:3],16))[2:]
    if len(ab)==12:
        sgn=1
        ex=int(ab[1:], 2)-1023
    else:
        sgn=0
        ex=int(ab, 2)-1023
    return(((-1)**sgn)*(1.0 + ((int(a[3:],16))/(2.0**52)))*(2**ex))
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top