Get memory representation of double

Discussion in 'C Programming' started by anders.weitman@home.se, Aug 4, 2007.

  1. Guest

    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
    , Aug 4, 2007
    #1
    1. Advertising

  2. >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.

    >}
    Gordon Burditt, Aug 4, 2007
    #2
    1. Advertising

  3. Mike Wahler Guest

    <> wrote in message
    news:...
    > 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);

    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
    Mike Wahler, Aug 4, 2007
    #3
  4. santosh Guest

    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
    santosh, Aug 4, 2007
    #4
  5. pete Guest

    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 == 8);
    assert(sizeof(short) == 2);
    assert(sizeof(double) == 8);
    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
    pete, Aug 4, 2007
    #5
  6. 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

    [ Please reply to the group,
    return address is invalid ]
    Roberto Waltman, Aug 4, 2007
    #6
  7. pete Guest

    pete wrote:
    >
    > 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 == 8);
    > assert(sizeof(short) == 2);
    > assert(sizeof(double) == 8);
    > 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));
    }
    return 0;
    }

    /* END new.c */


    --
    pete
    pete, Aug 4, 2007
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. SOndei
    Replies:
    0
    Views:
    401
    SOndei
    Jan 15, 2004
  2. Sydex
    Replies:
    12
    Views:
    6,450
    Victor Bazarov
    Feb 17, 2005
  3. Rajesh.Rapaka
    Replies:
    13
    Views:
    1,759
    Patricia Shanahan
    Jul 10, 2006
  4. Replies:
    5
    Views:
    499
  5. Clint Olsen

    Using a union to get different representation

    Clint Olsen, Jul 7, 2005, in forum: C Programming
    Replies:
    14
    Views:
    492
    Tim Rentsch
    Jul 13, 2005
Loading...

Share This Page