0

I need to convert double value to hex value;

#include <stdio.h>
#include <stdint.h>
uint64_t DoubleToHexCoverter(double f);

int main()
{
    a = 40.123456789;
    printf("Hex: %08x",DoubleToHexCoverter(a));

    return 0;
}

uint64_t DoubleToHexCoverter(double d)
{
  return (*(unsigned int*)&d);
}

I get this result:

Hex: 000000006e9b9cb2

I see half of the numbers. Other's full with zeros "00000000" How can I get all numbers correctly. I think uint64 value's keeping 32 bit + 32 bit values but I didnt do that please help me.

When I try below codes I get same result. EDIT:

uint64_t DoubleToHexCoverter(double f)
{
  return (*(uint64_t*)&f);
}
hobik
  • 439
  • 4
  • 15

3 Answers3

3

Are you trying to print the binary representation of the floating-point number, or are you trying to print the value in hex notation?

If it's the latter, just use the %a or %A conversions:

printf( "Hex: %a\n", a );

giving us

Hex:   0x1.40fcd6e9b9cb2p+5

If you want to print the binary representation of the number, a "safe" way of doing it is:

union rep
{
  double a;
  unsigned char bytes[ sizeof (double) ];
};

union rep r = {.a = 40.123456789 };

fputs( "Bytes: ", stdout );

for ( size_t i = 0; i < sizeof r.a; i++ )
  printf( "%02hhx ", r.bytes[i] );
putchar( '\n' );

giving us

Bytes: b2 9c 9b 6e cd 0f 44 40 

Since I'm on x86 which is little-endian, those bytes are ordered from least significant to most significant, so b2 represents the lowest 8 bytes of the value - it should actually be read as

40440fcd6e9b9cb2
John Bode
  • 119,563
  • 19
  • 122
  • 198
1

You want uint64_t, so you should cast to uint64_t*, not unsigned int*.

uint64_t DoubleToHexCoverter(double d)
{
  return (*(unsigned int*)&d);
}

Also using %x for printing uint64_t invokes undefined behavior because it is wrong type for %x, which expects unsigned int.

You should add #include <inttypes.h> and use PRIx64 macro like "%" PRIx64 to print uint64_t.

This may work in the real world, but this violates the strict aliasing rule and the behavior is not guaranteed. You can use memcpy() to copy bytes from objects to objects.

#include <string.h>
#include <assert.h>

uint64_t DoubleToHexCoverter(double d)
{
  uint64_t res;
  assert(sizeof(uint64_t) == sizeof(double));
  memcpy(&res, &d, sizeof(d));
  return res;
}
MikeCAT
  • 73,922
  • 11
  • 45
  • 70
-1

Try to use the appropriate length specifier for the printf() function:

#include <stdio.h>
#include <stdint.h>
uint64_t DoubleToHexCoverter(double f);

int main()
{
    double a = 40.123456789;
    printf("\nHex: %zx", DoubleToHexCoverter(a));

    return 0;
}

uint64_t DoubleToHexCoverter(double d)
{
  return (*(uint64_t*)&d);
}

I used the length specifier "z" from here: https://www.cplusplus.com/reference/cstdio/printf/

With that code i get the output:

Hex: 40440fcd6e9b9cb2