6

I have an unsigned long long (or uint64_t) value and want to convert it to a double. The double shall have the same bit pattern as the long value. This way I can set the bits of the double "by hand".

unsigned long long bits = 1ULL;
double result = /* some magic here */ bits;

I am looking for a way to do this.

pvorb
  • 6,845
  • 7
  • 44
  • 72
  • 2
    Are you asking how to do this? Having a hard time parsing a *question* out of this. – WhozCraig Jul 01 '13 at 16:21
  • 3
    In C99, you can legally do this via a union. In C++, you'd have to do it using a `memcpy()`. – Mysticial Jul 01 '13 at 16:23
  • If'n yer feelin' like bein' a dangerous badboy, yer tool o' choice would be somethin' like a [this here cast, young feller.](https://dl.dropboxusercontent.com/u/17644642/cowboy_cast.png) –  Jul 01 '13 at 16:36

3 Answers3

16

The portable way to do this is with memcpy (you may also be able to conditionally do it with reinterpret_cast or a union, but those aren't certain to be portable because they violate the letter of the strict-alias rules):

// First, static assert that the sizes are the same
memcpy(&result, &bits, sizeof(bits));

But before you do make sure you know exactly what you're doing and what floating point representation is being used (although IEEE754 is a popular/common choice). You'll want to avoid all kinds of problem values like infinity, NaN, and denormal numbers.

Mark B
  • 93,381
  • 10
  • 105
  • 184
  • Thanks for the explanation. – pvorb Jul 01 '13 at 16:34
  • 2
    I believe the standard actually allows you to "reinterpret_cast(bits)" in this case, as both types are standard-layout, assuming double doesn't require a more strict alignment. – DanielKO Jul 01 '13 at 21:48
6

Beware of union and reinterpret_cast<double*>(&bits), for both of these methods are UB. Pretty much all you can do is memcpy.

Puppy
  • 141,834
  • 35
  • 244
  • 454
-3

The following uses a void pointer.

unsigned long long bits = 1ULL;
void* tempPtr=(void*)&bits;
double result = *(double*)tempPtr;
IanPudney
  • 5,747
  • 1
  • 21
  • 37
  • 4
    Undefined behaviour- strict aliasing violation. This is the same as dasblinkenlight's answer but with a completely pointless temporary. – Puppy Jul 01 '13 at 16:29
  • I was aware that my answer is the same as dasblinkenlight's, but since it uses a completely different syntax it appears to be a different method. Thus, I felt it was appropriate to post as an answer to the question. And as for the fact that it is undefined behavior, I do not know of one compiler or system that is incapable of handlng this (provided both variables are the same size). – IanPudney Jul 01 '13 at 16:35
  • 2
    The addition of the temporary is utterly meaningless, the method is identical. Also, it's undefined behaviour, and that's that. – Puppy Jul 01 '13 at 16:36