Captain_Obvious - 1 year ago 69
C Question

# Two doubles with bits copied differently from a long are printed differently

As shown in the code below, I am trying to copy the bits from a long

`longnum`
to two doubles,
`d1`
and
`d2`
, using different methods: pointer-casting + dereferencing and 'bitwise-and'ing respectively.

``````# include <stdio.h>

int main(void) {
long longnum = 0xDDDDDDDDDDDDDDDD;
double d1 = *((double*)(&longnum));
double d2 = longnum & 0xFFFFFFFFFFFFFFFF;

printf("%ld\n\n",longnum);
printf("%lf\n\n",d1);
printf("%lf\n",d2);
return 0;
}
``````

The issue is that both the doubles are not printed the same way, as shown in the output below.

``````-2459565876494606883

-1456815990147462891125136942359339382185244158826619267593931664968442323048246672764155341958241671875972237215762610409185128240974392406835200.000000

15987178197214945280.000000
``````

Given the size of
`DBL_MAX`
, the max size of a double, it seems to me that it's the giant number that's actually the sensible output of the two doubles printed.

``````double d2 = longnum & 0xFFFFFFFFFFFFFFFF;
``````

The `&` mask doesn't do anything. A number ANDed with all 1's is the same number. The line above is no different from:

``````double d2 = longnum;
``````

That line doesn't do any bit reinterpretation. Instead it sets `d2` to the `double` that most closely represents the value in `longnum`. The value will be similar; the bit pattern will be quite different.

The best way to do what you're trying to do is with a union. Unions are the best way to perform type punning.

``````union {
long l;
double d;
} u;

u.l = longnum;
printf("%f\n\n", u.d);
``````

Using pointers as you did with `d1` technically invokes undefined behavior. It is a common idiom and in practice will probably work fine, but type punning with pointers ought to be avoided.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download