How to extract bytes from long?

Discussion in 'C Programming' started by RB, Oct 15, 2003.

  1. RB

    RB Guest

    How to extract bytes from long, starting from the last byte?
    For example, I have a long number:
    0x12345678
    I need to represent it as the following bytes list:
    0x78, 0x56, 0x34, 0x12

    Thanks in advance,
    Rita
     
    RB, Oct 15, 2003
    #1
    1. Advertising

  2. RB

    Ed Morton Guest

    RB wrote:
    > How to extract bytes from long, starting from the last byte?
    > For example, I have a long number:
    > 0x12345678
    > I need to represent it as the following bytes list:
    > 0x78, 0x56, 0x34, 0x12
    >
    > Thanks in advance,
    > Rita


    Sounds a bit homework-y, but as a hint try this:

    #include <stdio.h>

    int main(void)
    {
    long val=0x12345678;

    printf("0x%x\n",val >> 16 & 0xff );

    return 0;
    }

    Regards,

    Ed.
     
    Ed Morton, Oct 15, 2003
    #2
    1. Advertising

  3. On Wed, 15 Oct 2003 01:59:04 -0700, RB wrote:

    > How to extract bytes from long, starting from the last byte?


    #include <stdio.h>

    int main() {

    unsigned long value = 0x12345678;
    int i;

    printf("%#lx\n",value);

    for (i = sizeof value; i > 0; --i) {
    printf("%#x\n", value & 0xff);
    value >>= 8;
    }
    return 0;
    }

    --
    NPV

    "the large print giveth, and the small print taketh away"
    Tom Waits - Step right up
     
    Nils Petter Vaskinn, Oct 15, 2003
    #3
  4. RB wrote:
    > How to extract bytes from long, starting from the last byte?
    > For example, I have a long number:
    > 0x12345678
    > I need to represent it as the following bytes list:
    > 0x78, 0x56, 0x34, 0x12
    >
    > Thanks in advance,
    > Rita


    Look at bitwise operators. &, |, ^, <<, >>. Then look up bitmasks
    and how to use them and everything should be rather straightforward.

    --
    Thomas.
    "What is the future c existence which does not do in all languages"
     
    Thomas Stegen, Oct 15, 2003
    #4
  5. RB

    pete Guest

    Nils Petter Vaskinn wrote:
    >
    > On Wed, 15 Oct 2003 01:59:04 -0700, RB wrote:
    >
    > > How to extract bytes from long, starting from the last byte?

    >


    #include <limits.h>
    > #include <stdio.h>
    >
    > int main() {
    >
    > unsigned long value = 0x12345678;
    > int i;
    >
    > printf("%#lx\n",value);
    >
    > for (i = sizeof value; i > 0; --i) {
    > printf("%#x\n", value & 0xff);
    > value >>= 8;


    /*
    ** You realise that you don't know the size of value,
    ** so you might as well go all the way.
    */
    printf("%#x\n", value & (unsigned char)-1);
    value >>= CHAR_BIT;

    > }
    > return 0;
    > }


    --
    pete
     
    pete, Oct 15, 2003
    #5
  6. RB

    pete Guest

    pete wrote:
    >
    > Nils Petter Vaskinn wrote:
    > >
    > > On Wed, 15 Oct 2003 01:59:04 -0700, RB wrote:
    > >
    > > > How to extract bytes from long, starting from the last byte?


    .... and now for the (sizeof(long)==1) portable way:

    /* BEGIN new.c */

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

    int main(void)
    {
    unsigned long value = 0x12345678;
    size_t i;

    printf("%#lx\n",value);
    printf("%#x\n", value & (unsigned char)-1);
    for (i = sizeof value - 1; i != 0; --i) {
    value >>= CHAR_BIT;
    printf("%#x\n", value & (unsigned char)-1);
    }
    return 0;
    }

    /* END new.c */

    and now for the way which interprets "last byte"
    as being the one furthest from ((char*)&value)

    /* BEGIN new2.c */

    #include <stdio.h>

    int main(void)
    {
    unsigned long value = 0x12345678;
    unsigned char *pointer = (unsigned char*)&value + sizeof value;

    printf("%#lx\n",value);
    do {
    --pointer;
    printf("%#x\n", (unsigned)*pointer);
    } while (pointer != (unsigned char*)&value);
    return 0;
    }

    /* END new2.c */

    --
    pete
     
    pete, Oct 15, 2003
    #6
  7. RB

    John Bode Guest

    (RB) wrote in message news:<>...
    > How to extract bytes from long, starting from the last byte?
    > For example, I have a long number:
    > 0x12345678
    > I need to represent it as the following bytes list:
    > 0x78, 0x56, 0x34, 0x12
    >
    > Thanks in advance,
    > Rita


    There are a couple of ways. The safest is to use a bitmask (0xFF),
    the bitwise & operator, and the >> and << shift operators.
    Alternately, you can treat the long as an array of unsigned char by
    creating an unsigned char pointer and setting it to the same address
    as the long (unsigned char *p = (unsigned char *) &mylong;) and then
    either use array subscript notation to access individual bytes or
    "walk" the array by incrementing p, but you have to be aware of
    endianness issues (i.e., on a little-endian machine, p[0] would be the
    LSB, whereas on a big-endian machine it would be the MSB). The first
    method (bitmask and shift) works the same regardless of endian issues.
     
    John Bode, Oct 15, 2003
    #7
  8. pete <> wrote in message news:<>...
    > pete wrote:
    > >
    > > Nils Petter Vaskinn wrote:
    > > >
    > > > On Wed, 15 Oct 2003 01:59:04 -0700, RB wrote:
    > > >
    > > > > How to extract bytes from long, starting from the last byte?

    >
    > ... and now for the (sizeof(long)==1) portable way:

    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    >
    > /* BEGIN new.c */
    >
    > #include <stdio.h>
    > #include <limits.h>
    >
    > int main(void)
    > {
    > unsigned long value = 0x12345678;
    > size_t i;
    >
    > printf("%#lx\n",value);
    > printf("%#x\n", value & (unsigned char)-1);
    > for (i = sizeof value - 1; i != 0; --i) {
    > value >>= CHAR_BIT;


    UB if sizeof(long) == 1.

    value = value >> (CHAR_BIT - 1) >> 1;

    > printf("%#x\n", value & (unsigned char)-1);
    > }
    > return 0;
    > }
    >
    > /* END new.c */


    --
    Peter
     
    Peter Nilsson, Oct 16, 2003
    #8
  9. RB

    CBFalconer Guest

    pete wrote:
    > Nils Petter Vaskinn wrote:
    > > On Wed, 15 Oct 2003 01:59:04 -0700, RB wrote:
    > >
    > > > How to extract bytes from long, starting from the last byte?

    >
    > #include <limits.h>
    > > #include <stdio.h>
    > >
    > > int main() {
    > >
    > > unsigned long value = 0x12345678;
    > > int i;
    > >
    > > printf("%#lx\n",value);
    > >
    > > for (i = sizeof value; i > 0; --i) {
    > > printf("%#x\n", value & 0xff);
    > > value >>= 8;

    >
    > /*
    > ** You realise that you don't know the size of value,
    > ** so you might as well go all the way.
    > */
    > printf("%#x\n", value & (unsigned char)-1);
    > value >>= CHAR_BIT;
    >
    > > }
    > > return 0;
    > > }


    You need neither CHAR_BIT nor shifts nor limits.h nor sizeof:

    for (i = 8; i > 0; --i) {
    printf("%x ", value % 256);
    value /= 256;
    }
    putchar('\n'); /* <--AND HERE is where the \n goes */
    return 0;
    }

    and the result is portable.

    --
    Chuck F () ()
    Available for consulting/temporary embedded and systems.
    <http://cbfalconer.home.att.net> USE worldnet address!
     
    CBFalconer, Oct 16, 2003
    #9
  10. pete <> wrote in message news:<>...
    > printf("%#x\n", value & (unsigned char)-1);
    > for (i = sizeof value - 1; i != 0; --i) {
    > value >>= CHAR_BIT;
    > printf("%#x\n", value & (unsigned char)-1);
    > }
    > return 0;
    > }


    I would use ~0 for "all 1s" rather than -1.

    Sam
     
    Samuel Barber, Oct 16, 2003
    #10
  11. (Samuel Barber) wrote in message news:<>...
    > pete <> wrote in message news:<>...
    > > printf("%#x\n", value & (unsigned char)-1);
    > > for (i = sizeof value - 1; i != 0; --i) {
    > > value >>= CHAR_BIT;
    > > printf("%#x\n", value & (unsigned char)-1);
    > > }
    > > return 0;
    > > }

    >
    > I would use ~0 for "all 1s" rather than -1.


    That risks a trap representation under C99.

    --
    Peter
     
    Peter Nilsson, Oct 16, 2003
    #11
  12. RB

    pete Guest

    Peter Nilsson wrote:
    >
    > pete <> wrote in message news:<>...
    > > pete wrote:
    > > >
    > > > Nils Petter Vaskinn wrote:
    > > > >
    > > > > On Wed, 15 Oct 2003 01:59:04 -0700, RB wrote:
    > > > >
    > > > > > How to extract bytes from long, starting from the last byte?

    > >
    > > ... and now for the (sizeof(long)==1) portable way:

    > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    > >
    > > /* BEGIN new.c */
    > >
    > > #include <stdio.h>
    > > #include <limits.h>
    > >
    > > int main(void)
    > > {
    > > unsigned long value = 0x12345678;
    > > size_t i;
    > >
    > > printf("%#lx\n",value);
    > > printf("%#x\n", value & (unsigned char)-1);
    > > for (i = sizeof value - 1; i != 0; --i) {
    > > value >>= CHAR_BIT;

    >
    > UB if sizeof(long) == 1.


    No.
    If sizeof(long) == 1,
    then the loop doesn't execute.

    > > printf("%#x\n", value & (unsigned char)-1);
    > > }
    > > return 0;
    > > }
    > >
    > > /* END new.c */


    --
    pete
     
    pete, Oct 17, 2003
    #12
  13. (Peter Nilsson) wrote in message news:<>...
    > (Samuel Barber) wrote in message news:<>...
    > > pete <> wrote in message news:<>...
    > > > printf("%#x\n", value & (unsigned char)-1);
    > > > for (i = sizeof value - 1; i != 0; --i) {
    > > > value >>= CHAR_BIT;
    > > > printf("%#x\n", value & (unsigned char)-1);
    > > > }
    > > > return 0;
    > > > }

    > >
    > > I would use ~0 for "all 1s" rather than -1.

    >
    > That risks a trap representation under C99.


    Nonsense. ~0 is idiomatic C. Aren't you worried about the "risk" that
    -1 may not be implemented as all-1s? That is, after all, an
    implementation detail. It's not true for sign-magnitude or 1's
    complement, for example.

    Sam
     
    Samuel Barber, Oct 17, 2003
    #13
  14. RB

    pete Guest

    CBFalconer wrote:
    >
    > pete wrote:
    > > Nils Petter Vaskinn wrote:
    > > > On Wed, 15 Oct 2003 01:59:04 -0700, RB wrote:
    > > >
    > > > > How to extract bytes from long, starting from the last byte?

    > >
    > > #include <limits.h>
    > > > #include <stdio.h>
    > > >
    > > > int main() {
    > > >
    > > > unsigned long value = 0x12345678;
    > > > int i;
    > > >
    > > > printf("%#lx\n",value);
    > > >
    > > > for (i = sizeof value; i > 0; --i) {
    > > > printf("%#x\n", value & 0xff);
    > > > value >>= 8;

    > >
    > > /*
    > > ** You realise that you don't know the size of value,
    > > ** so you might as well go all the way.
    > > */
    > > printf("%#x\n", value & (unsigned char)-1);
    > > value >>= CHAR_BIT;
    > >
    > > > }
    > > > return 0;
    > > > }

    >
    > You need neither CHAR_BIT nor shifts nor limits.h nor sizeof:
    >
    > for (i = 8; i > 0; --i) {
    > printf("%x ", value % 256);
    > value /= 256;
    > }
    > putchar('\n'); /* <--AND HERE is where the \n goes */
    > return 0;
    > }
    >
    > and the result is portable.


    I was addressing the more general subject,
    in the subject line of this thread: "How to extract bytes from long?",
    rather than how to extract bytes from 0x12345678
    or any other number which doesn't require more than 32 bits.

    --
    pete
     
    pete, Oct 17, 2003
    #14
  15. RB

    pete Guest

    Samuel Barber wrote:
    >
    > (Peter Nilsson) wrote in message news:<>...
    > > (Samuel Barber) wrote in message news:<>...
    > > > pete <> wrote in message news:<>...
    > > > > printf("%#x\n", value & (unsigned char)-1);
    > > > > for (i = sizeof value - 1; i != 0; --i) {
    > > > > value >>= CHAR_BIT;
    > > > > printf("%#x\n", value & (unsigned char)-1);
    > > > > }
    > > > > return 0;
    > > > > }
    > > >
    > > > I would use ~0 for "all 1s" rather than -1.

    > >
    > > That risks a trap representation under C99.

    >
    > Nonsense. ~0 is idiomatic C. Aren't you worried about the "risk" that
    > -1 may not be implemented as all-1s? That is, after all, an
    > implementation detail. It's not true for sign-magnitude or 1's
    > complement, for example.


    You're wrong about everything.

    ~0 is negative zero in ones complement.
    Implementations are allowed trap negative zero.

    -1 is a value, not a bit pattern.
    The value of negative one, cast to unsigned char, is UCHAR_MAX.

    --
    pete
     
    pete, Oct 17, 2003
    #15
  16. On Fri, 17 Oct 2003 02:44:03 +0000, pete wrote:

    > Samuel Barber wrote:
    >>
    >> (Peter Nilsson) wrote in message news:<>...
    >> > (Samuel Barber) wrote in message news:<>...
    >> > > pete <> wrote in message news:<>...
    >> > > > printf("%#x\n", value & (unsigned char)-1);
    >> > > > for (i = sizeof value - 1; i != 0; --i) {
    >> > > > value >>= CHAR_BIT;
    >> > > > printf("%#x\n", value & (unsigned char)-1);
    >> > > > }
    >> > > > return 0;
    >> > > > }
    >> > >
    >> > > I would use ~0 for "all 1s" rather than -1.
    >> >
    >> > That risks a trap representation under C99.

    >>
    >> Nonsense. ~0 is idiomatic C. Aren't you worried about the "risk" that
    >> -1 may not be implemented as all-1s? That is, after all, an
    >> implementation detail. It's not true for sign-magnitude or 1's
    >> complement, for example.

    >
    > You're wrong about everything.
    >
    > ~0 is negative zero in ones complement.
    > Implementations are allowed trap negative zero.


    ~0u cannot be a trap representation, however.

    6.5.3.3
    4 The result of the ~ operator is the bitwise complement of its
    (promoted) operand ... If the promoted type is an unsigned type,
    the expression ~E is equivalent to the maximum value representable
    in that type minus E.

    > -1 is a value, not a bit pattern.
    > The value of negative one, cast to unsigned char, is UCHAR_MAX.
     
    Sheldon Simms, Oct 17, 2003
    #16
  17. pete <> wrote in message news:<>...
    > Samuel Barber wrote:
    > >
    > > (Peter Nilsson) wrote in message news:<>...
    > > > (Samuel Barber) wrote in message news:<>...
    > > > > pete <> wrote in message news:<>...
    > > > > > printf("%#x\n", value & (unsigned char)-1);
    > > > > > for (i = sizeof value - 1; i != 0; --i) {
    > > > > > value >>= CHAR_BIT;
    > > > > > printf("%#x\n", value & (unsigned char)-1);
    > > > > > }
    > > > > > return 0;
    > > > > > }
    > > > >
    > > > > I would use ~0 for "all 1s" rather than -1.
    > > >
    > > > That risks a trap representation under C99.

    > >
    > > Nonsense. ~0 is idiomatic C. Aren't you worried about the "risk" that
    > > -1 may not be implemented as all-1s? That is, after all, an
    > > implementation detail. It's not true for sign-magnitude or 1's
    > > complement, for example.

    >
    > You're wrong about everything.
    >
    > ~0 is negative zero in ones complement.
    > Implementations are allowed trap negative zero.


    You're just repeating words, without any understanding. There's no
    such thing as "negative zero" (or negative anything) in the context of
    bitwise operations. How can a bitwise operation trap? It can't.

    > -1 is a value, not a bit pattern.
    > The value of negative one, cast to unsigned char, is UCHAR_MAX.


    Hello? The point is that -1 is ***being used as*** a bit pattern. The
    intent is to get "all 1s", which is true if the integer representation
    is 2's complement; that's an implicit assumption of the code. (This is
    the best reason not to use -1: the intent is not perfectly clear).

    Sam
     
    Samuel Barber, Oct 17, 2003
    #17
  18. On Fri, 16 Oct 2003, Samuel Barber wrote:
    >
    > pete wrote in message news:<>...
    > > Samuel Barber wrote:
    > > > (Peter Nilsson) wrote...
    > > > > Samuel Barber wrote...
    > > > > > pete wrote in message news:<>...
    > > > > > >
    > > > > > > printf("%#x\n", value & (unsigned char)-1);
    > > > > >
    > > > > > I would use ~0 for "all 1s" rather than -1.
    > > > >
    > > > > That risks a trap representation under C99.
    > > >
    > > > Nonsense. ~0 is idiomatic C. Aren't you worried about the "risk" that
    > > > -1 may not be implemented as all-1s? That is, after all, an
    > > > implementation detail. It's not true for sign-magnitude or 1's
    > > > complement, for example.

    > >
    > > You're wrong about everything.
    > >
    > > ~0 is negative zero in ones complement.
    > > Implementations are allowed trap negative zero.

    >
    > You're just repeating words, without any understanding. There's no
    > such thing as "negative zero" (or negative anything) in the context of
    > bitwise operations.


    It is AFAIK implementation-defined whether the concept of "negative
    zero" is meaningful in standard C (depending on the representation
    of signed integers).

    > How can a bitwise operation trap? It can't.


    Of course it can! (Why wouldn't it? And do modern digital computers
    perform any operations that *aren't* bitwise, anyway?)

    > > -1 is a value, not a bit pattern.
    > > The value of negative one, cast to unsigned char, is UCHAR_MAX.


    To clarify pete's point:

    (uchar)-1 == (uchar)-((int)1) == (-(int)1)+UCHAR_MAX == UCHAR_MAX-1

    ....which is guaranteed to have an all-ones bit pattern, regardless
    of padding or n's-complement.


    > Hello? The point is that -1 is ***being used as*** a bit pattern.


    Then it's being used incorrectly. -1 is *not* a bit pattern, it's
    an integer expression equal to the additive inverse of the integer 1.
    It doesn't have a "bit pattern" per se.

    > The intent is to get "all 1s", which is true if the integer
    > representation is 2's complement; that's an implicit assumption
    > of the code.


    If that *were* an implicit assumption of the code, then the code
    would be broken. But it's not. Pete's code AFAICT doesn't assume
    anything earth-shattering about the integer representations used
    by the target system.

    > (This is the best reason not to use -1: the intent is not
    > perfectly clear).


    However, it *does* produce the right answer, which is a point in
    its favor. ~0 might trap, and in any case I think (unsigned char)-1
    has a bit more aesthetic value to it (YMMV, of course).

    And if you want everything to be *perfectly* clear, then you might
    want to consider a different programming language. C is just
    full of 'for (i=0; a; ++i)'s and 'while (*s++ = *t++)'s; if
    a simple -1 throws you, then you're in trouble. :)

    -Arthur
     
    Arthur J. O'Dwyer, Oct 17, 2003
    #18
  19. On Thu, 16 Oct 2003 23:53:05 -0700, Samuel Barber wrote:

    > pete <> wrote in message news:<>...
    >> Samuel Barber wrote:
    >> >
    >> > (Peter Nilsson) wrote in message news:<>...
    >> > > (Samuel Barber) wrote in message news:<>...
    >> > > > pete <> wrote in message news:<>...
    >> > > > > printf("%#x\n", value & (unsigned char)-1);
    >> > > > > for (i = sizeof value - 1; i != 0; --i) {
    >> > > > > value >>= CHAR_BIT;
    >> > > > > printf("%#x\n", value & (unsigned char)-1);
    >> > > > > }
    >> > > > > return 0;
    >> > > > > }
    >> > > >
    >> > > > I would use ~0 for "all 1s" rather than -1.
    >> > >
    >> > > That risks a trap representation under C99.
    >> >
    >> > Nonsense. ~0 is idiomatic C. Aren't you worried about the "risk" that
    >> > -1 may not be implemented as all-1s? That is, after all, an
    >> > implementation detail. It's not true for sign-magnitude or 1's
    >> > complement, for example.

    >>
    >> You're wrong about everything.
    >>
    >> ~0 is negative zero in ones complement.
    >> Implementations are allowed trap negative zero.

    >
    > You're just repeating words, without any understanding. There's no
    > such thing as "negative zero" (or negative anything) in the context of
    > bitwise operations. How can a bitwise operation trap? It can't.


    6.2.6.2 Integer types
    2 ... (It is implementation-defined) whether the value with ...
    sign bit 1 and all value bits 1 (for one's complement), is a trap
    representation or a normal value. In the case of ... one's
    complement, if this representation is a normal value it is called
    a negative zero.
    ...
    3 If the implementation supports negative zeros, they shall be
    generated only by: the &, |, ^, ~, <<, and >> operators with
    arguments that produce such a value;
    ...
    4 If the implementation does not support negative zeros, the
    behavior of the &, |, ^, ~, <<, and >> operators with arguments
    that would produce such a value is undefined.
     
    Sheldon Simms, Oct 17, 2003
    #19
  20. RB

    Jirka Klaue Guest

    Arthur J. O'Dwyer wrote:
    ....
    > (uchar)-1 == (uchar)-((int)1) == (-(int)1)+UCHAR_MAX == UCHAR_MAX-1


    You must have miscalculated somewhere. (uc)-1 should be UCHAR_MAX.

    (uc)-1 == (uc)(0 - 1) == (uc)(UINT_MAX + 1 - 1) == (uc)(UINT_MAX) == UCHAR_MAX

    Jirka
     
    Jirka Klaue, Oct 17, 2003
    #20
    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. George Marsaglia

    Assigning unsigned long to unsigned long long

    George Marsaglia, Jul 8, 2003, in forum: C Programming
    Replies:
    1
    Views:
    682
    Eric Sosman
    Jul 8, 2003
  2. Curt Geske

    How to extract bytes from a long?

    Curt Geske, Oct 15, 2003, in forum: C Programming
    Replies:
    46
    Views:
    1,094
    Peter Shaggy Haywood
    Oct 21, 2003
  3. Daniel Rudy

    unsigned long long int to long double

    Daniel Rudy, Sep 19, 2005, in forum: C Programming
    Replies:
    5
    Views:
    1,194
    Peter Shaggy Haywood
    Sep 20, 2005
  4. Yandos
    Replies:
    12
    Views:
    5,125
    Pete Becker
    Sep 15, 2005
  5. Replies:
    5
    Views:
    288
    dprody
    Nov 5, 2007
Loading...

Share This Page