#include <stdio.h>
typedef unsigned char*pointer;
void show_bytes(pointer start, size_t len)
{
size_t i;
for (i = 0; i < len; i++)
printf("%p\t0x%04x\n",start+i, start[i]);
printf("\n");
}
int main()
{
double a = 4.75;
printf("Double demo by %s on %s %s\n", "Toan Tran", __DATE__, __TIME__);
printf("Double a = %.2f (0x%08x)\n", a, a);
show_bytes((pointer) &a, sizeof(double));
}
Output:
Double demo by Toan Tran on Nov 8 2018 11:07:07
Double a = 4.75 (0x00000100)
0x7ffeee7a0b38 0x0000
0x7ffeee7a0b39 0x0000
0x7ffeee7a0b3a 0x0000
0x7ffeee7a0b3b 0x0000
0x7ffeee7a0b3c 0x0000
0x7ffeee7a0b3d 0x0000
0x7ffeee7a0b3e 0x0013
0x7ffeee7a0b3f 0x0040
For this line:
printf("Double a = %.2f (0x%08x)\n", a, a);
I want it to print out the result of start[i]
The return hexadecimal is not the right value for double.
I want it to return 0x40130000000000...
Please help.
The %x
format specifier is expecting an unsigned int
argument, but you're passing in a double
. Using the wrong format specifier invokes undefined behavior.
To print the representation of a double
, you need to print each individual byte as hex using a character pointer. This is exactly what you're doing in show_bytes
, and is the proper way to do this.
Also, when printing a pointer with the %p
format specifier, you should cast the pointer to void *
, which is what %p
expects. This is one of the rare cases where a cast to void *
is needed.
You might be tempted to do something like this:
printf("%llx", *((unsigned long long *)&a));
However this is a violation of the strict aliasing rule. You would need to use memcpy
to copy the bytes to the other type:
static_assert(sizeof(unsigned long long) == sizeof(double));
unsigned long long b;
memcpy(&b, &a, sizeof(a));
printf("%llx", b);
You can also do this with a union:
union dval {
double d;
unsigned long long u;
};
union dval v;
v.d = d;
printf("%llx", v.u);
To allow printing a hex dump of any object, pass its address and length.
void show_bytes2(void *start, size_t size) {
int nibble_width_per_byte = (CHAR_BIT + 3) / 4; // Often 2
unsigned char *mem = start;
// Highest bytes first
for (size_t i = size; i>0; ) {
printf("%0*x", nibble_width_per_byte, mem[--i]);
}
printf("\n");
// Lowest bytes first
while (size--) {
printf("%0*x", nibble_width_per_byte, *mem++);
}
printf("\n");
}
Use "%a"
to print the significand of the double
in hexadecimal.
int main() {
double a = 4.75;
printf("Double a = %a %e %f %g\n", a, a, a, a);
show_bytes2(&a, sizeof a);
}
Output
Double a = 0x1.3p+2 4.750000e+00 4.750000 4.75
4013000000000000 // I want it to return 0x40130000000000...
0000000000001340
User contributions licensed under CC BY-SA 3.0