Velocity Reviews > Get memory representation of double

# Get memory representation of double

anders.weitman@home.se
Guest
Posts: n/a

 08-04-2007
Hi!

I want to get the representation in memory of a variable of type
double and put it in an array of four unsigned short int (I'm on a 32-
bits Windows architecture so a double is 64-bits and an unsigned short
int is 16-bits).

For example, the double precision representation of 1/3 is 3fd5 5555
5555 5555 (hex).

I tried to do a simple cast from a pointer of type double to a pointer
to an array of unsigned short int but does not seem to work. I'm not
very good a C programming so help is very much appreciated.

#include <stdio.h>

void double_to_uint16(double *in, unsigned short int *out)
{
out = (unsigned short int *)in;
}

main()
{
double a = 0.3333333333333333;
unsigned short int b[4];

double_to_uint16(&a, b);

printf("1: %hx\n", b[0]);
printf("2: %hx\n", b[1]);
printf("3: %hx\n", b[2]);
printf("4: %hx\n", b[3]);
}

The program above gives the following printout:

1: f000
2: 6113
3: 0
4: 0

But I expected to get:

1: 3fd5
2: 5555
3: 5555
4: 5555

Gordon Burditt
Guest
Posts: n/a

 08-04-2007
>For example, the double precision representation of 1/3 is 3fd5 5555
>5555 5555 (hex).
>
>I tried to do a simple cast from a pointer of type double to a pointer
>to an array of unsigned short int but does not seem to work. I'm not
>very good a C programming so help is very much appreciated.
>
>
>#include <stdio.h>
>
>void double_to_uint16(double *in, unsigned short int *out)
>{
> out = (unsigned short int *)in;

Don't you mean:
*out = (unsigned short int *)in;
and this will only copy *one* short int, so you want to copy
sizeof(double)/sizeof(unsigned short int) times, moving to
the next unsigned short int each time.

>}

Mike Wahler
Guest
Posts: n/a

 08-04-2007

<(E-Mail Removed)> wrote in message
news:(E-Mail Removed) ups.com...
> Hi!
>
> I want to get the representation in memory of a variable of type
> double and put it in an array of four unsigned short int (I'm on a 32-
> bits Windows architecture so a double is 64-bits and an unsigned short
> int is 16-bits).
>
> For example, the double precision representation of 1/3 is 3fd5 5555
> 5555 5555 (hex).
>
> I tried to do a simple cast from a pointer of type double to a pointer
> to an array of unsigned short int but does not seem to work. I'm not
> very good a C programming so help is very much appreciated.
>
>
> #include <stdio.h>
>
> void double_to_uint16(double *in, unsigned short int *out)
> {
> out = (unsigned short int *)in;
> }
>
> main()
> {
> double a = 0.3333333333333333;
> unsigned short int b[4];
>
> double_to_uint16(&a, b);
>
> printf("1: %hx\n", b[0]);
> printf("2: %hx\n", b[1]);
> printf("3: %hx\n", b[2]);
> printf("4: %hx\n", b[3]);
> }
>
>
> The program above gives the following printout:
>
> 1: f000
> 2: 6113
> 3: 0
> 4: 0
>
> But I expected to get:
>
> 1: 3fd5
> 2: 5555
> 3: 5555
> 4: 5555

Why?

#include <stdio.h>

int main(void)
{
double d = 1.0 / 3;
unsigned char *p = (unsigned char *)&d;

printf("type 'double' object 'd' at address %p has value of %.16f\n",
(void*)&d, d);

size_t i = 0;

for(; i < sizeof d; ++i)
printf("byte %lu at address %p == %X\n",
(unsigned int)i, (void*)(p + i), p[i]);

return 0;
}

Output (MS VC++ 2005 Express, Pentium IV):

type 'double' object 'd' at address 0013FF6C has value of 0.3333333333333333
byte 0 at address 0013FF6C == 55
byte 1 at address 0013FF6D == 55
byte 2 at address 0013FF6E == 55
byte 3 at address 0013FF6F == 55
byte 4 at address 0013FF70 == 55
byte 5 at address 0013FF71 == 55
byte 6 at address 0013FF72 == D5
byte 7 at address 0013FF73 == 3F

-Mike

santosh
Guest
Posts: n/a

 08-04-2007
http://www.velocityreviews.com/forums/(E-Mail Removed) wrote:

> Hi!
>
> I want to get the representation in memory of a variable of type
> double and put it in an array of four unsigned short int (I'm on a 32-
> bits Windows architecture so a double is 64-bits and an unsigned short
> int is 16-bits).

If you want the bit representation of an object, the easiest way is to
access it as an array of unsigned char.

> For example, the double precision representation of 1/3 is 3fd5 5555
> 5555 5555 (hex).

The representation is implementation specific.

> I tried to do a simple cast from a pointer of type double to a pointer
> to an array of unsigned short int but does not seem to work. I'm not
> very good a C programming so help is very much appreciated.

Try this -

#include <stdio.h>

int main(void) {
double d = 1.0/3.0;
unsigned char *drep = 0;
int ctr;

printf("d = %f\n", d);
drep = (unsigned char *)&d;
for(ctr = 0; ctr < sizeof(double); ctr++) {
printf("d (byte %d) = %x\n", ctr, drep[ctr]);
}
return 0;
}

Output

d = 0.333333
d (byte 0) = 55
d (byte 1) = 55
d (byte 2) = 55
d (byte 3) = 55
d (byte 4) = 55
d (byte 5) = 55
d (byte 6) = d5
d (byte 7) = 3f

pete
Guest
Posts: n/a

 08-04-2007
(E-Mail Removed) wrote:
>
> Hi!
>
> I want to get the representation in memory of a variable of type
> double and put it in an array of four unsigned short int (I'm on a 32-
> bits Windows architecture so a double is 64-bits and an unsigned short
> int is 16-bits).
>
> For example, the double precision representation of 1/3 is 3fd5 5555
> 5555 5555 (hex).
>
> I tried to do a simple cast from a pointer of type double to a pointer
> to an array of unsigned short int but does not seem to work. I'm not
> very good a C programming so help is very much appreciated.
>
> #include <stdio.h>
>
> void double_to_uint16(double *in, unsigned short int *out)
> {
> out = (unsigned short int *)in;
> }
>
> main()
> {
> double a = 0.3333333333333333;
> unsigned short int b[4];
>
> double_to_uint16(&a, b);
>
> printf("1: %hx\n", b[0]);
> printf("2: %hx\n", b[1]);
> printf("3: %hx\n", b[2]);
> printf("4: %hx\n", b[3]);
> }
>
> The program above gives the following printout:
>
> 1: f000
> 2: 6113
> 3: 0
> 4: 0
>
> But I expected to get:
>
> 1: 3fd5
> 2: 5555
> 3: 5555
> 4: 5555

/* BEGIN new.c */

#include <stdio.h>
#include <limits.h>
#include <assert.h>

void double_to_uint16(double *in, unsigned short int *out)
{
size_t index;

assert(CHAR_BIT == ;
assert(sizeof(short) == 2);
assert(sizeof(double) == ;
for (index = 0; index != 4; ++index) {
out[index] = ((unsigned short *)in)[index];
}
}

int main(void)
{
double a = 1.0 / 3;
unsigned short int b[4];

double_to_uint16(&a, b);
printf("1: %hx\n", b[0]);
printf("2: %hx\n", b[1]);
printf("3: %hx\n", b[2]);
printf("4: %hx\n", b[3]);
return 0;
}

/* END new.c */

--
pete

Roberto Waltman
Guest
Posts: n/a

 08-04-2007
(E-Mail Removed) wrote:
>I want to get the representation in memory of a variable of type
>double and put it in an array of four unsigned short int (I'm on a 32-
>bits Windows architecture so a double is 64-bits and an unsigned short
>int is 16-bits).
>
>#include <stdio.h>
>void double_to_uint16(double *in, unsigned short int *out)
>{
> out = (unsigned short int *)in;
>}

I would just copy the memory contents:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main(void)
{
double src = 0.333333333333333333333;
unsigned short dst[4];

if (sizeof dst == sizeof src)
{
memcpy(dst, &src, sizeof src);
}
else
{
puts("Size mismatch");
return EXIT_FAILURE;
}

printf("1: %hx\n", dst[0]);
printf("2: %hx\n", dst[1]);
printf("3: %hx\n", dst[2]);
printf("4: %hx\n", dst[3]);

return EXIT_SUCCESS;
}

On an AMD/Linux/gcc platform it prints the values you expect, but on
the opposite order. The same is most likely to happen under Windows.

Roberto Waltman

pete
Guest
Posts: n/a

 08-04-2007
pete wrote:
>
> (E-Mail Removed) wrote:
> >
> > Hi!
> >
> > I want to get the representation in memory of a variable of type
> > double and put it in an array of four unsigned short int (I'm on a 32-
> > bits Windows architecture so a double is 64-bits and an unsigned short
> > int is 16-bits).
> >
> > For example, the double precision representation of 1/3 is 3fd5 5555
> > 5555 5555 (hex).
> >
> > I tried to do a simple cast from a pointer of type double to a pointer
> > to an array of unsigned short int but does not seem to work. I'm not
> > very good a C programming so help is very much appreciated.
> >
> > #include <stdio.h>
> >
> > void double_to_uint16(double *in, unsigned short int *out)
> > {
> > out = (unsigned short int *)in;
> > }
> >
> > main()
> > {
> > double a = 0.3333333333333333;
> > unsigned short int b[4];
> >
> > double_to_uint16(&a, b);
> >
> > printf("1: %hx\n", b[0]);
> > printf("2: %hx\n", b[1]);
> > printf("3: %hx\n", b[2]);
> > printf("4: %hx\n", b[3]);
> > }
> >
> > The program above gives the following printout:
> >
> > 1: f000
> > 2: 6113
> > 3: 0
> > 4: 0
> >
> > But I expected to get:
> >
> > 1: 3fd5
> > 2: 5555
> > 3: 5555
> > 4: 5555

>
> /* BEGIN new.c */
>
> #include <stdio.h>
> #include <limits.h>
> #include <assert.h>
>
> void double_to_uint16(double *in, unsigned short int *out)
> {
> size_t index;
>
> assert(CHAR_BIT == ;
> assert(sizeof(short) == 2);
> assert(sizeof(double) == ;
> for (index = 0; index != 4; ++index) {
> out[index] = ((unsigned short *)in)[index];
> }
> }

That for loop, makes an assumption about alignment
that may not be true.

For raw memory representation,
you can't go wrong with bytes of unsigned char.

/* BEGIN new.c */

#include <stdio.h>

int main(void)
{
double a = 1.0 / 3;
size_t i;

for (i = 0; i != sizeof a; ++i) {
printf("%u: %x\n", (unsigned)i, ((unsigned char *)&a)[i]);
}
return 0;
}

/* END new.c */

--
pete