Exact binary representation of a double [duplicate

2020-03-21 10:47发布

问题:

This question already has answers here:
Closed 8 years ago.

Possible Duplicate:
Float to binary in C++

I have a very small double var, and when I print it I get -0. (using C++). Now in order to get better precision I tried using

cout.precision(18); \\i think 18 is the max precision i can get.
cout.setf(ios::fixed,ios::floatfield);
cout<<var;\\var is a double.

but it just writes -0.00000000000...

I want to see the exact binary representation of the var.

In other words I want to see what binary number is written in the stack memory/register for this var.

回答1:

union myUnion {
    double dValue;
    uint64_t iValue;
};

myUnion myValue;
myValue.dValue=123.456;
cout << myValue.iValue;

Update:

The version above will work for most purposes, but it assumes 64 bit doubles. This version makes no assumptions and generates a binary representation:

    double someDouble=123.456;
    unsigned char rawBytes[sizeof(double)];

    memcpy(rawBytes,&someDouble,sizeof(double));

    //The C++ standard does not guarantee 8-bit bytes
    unsigned char startMask=1;
    while (0!=static_cast<unsigned char>(startMask<<1)) {
        startMask<<=1;
    }

    bool hasLeadBit=false;   //set this to true if you want to see leading zeros

    size_t byteIndex;
    for (byteIndex=0;byteIndex<sizeof(double);++byteIndex) {
        unsigned char bitMask=startMask;
        while (0!=bitMask) {
            if (0!=(bitMask&rawBytes[byteIndex])) {
                std::cout<<"1";
                hasLeadBit=true;
            } else if (hasLeadBit) {
                std::cout<<"0";
            }
            bitMask>>=1;
        }
    }
    if (!hasLeadBit) {
        std::cout<<"0";
    }


回答2:

This way is guaranteed to work by the standard:

double d = -0.0;
uint64_t u;
memcpy(&u, &d, sizeof(d));
std::cout << std::hex << u;


回答3:

Try:

printf("0x%08x\n", myFloat);

This should work for a 32 bit variable, to display it in hex. I've never tried using this technique to see a 64 bit variable, but I think it's:

printf("%016llx\n", myDouble);

EDIT: tested the 64-bit version and it definitely works on Win32 (I seem to recall the need for uppercase LL on GCC.. maybe)

EDIT2: if you really want binary, you are best off using one of the other answers to get a uint64_t version of your double, and then looping:

for ( int i = 63; i >= 0; i-- )
{
    printf( "%d", (myUint64 >> i ) & 1 );
}