446,368 Members | 1,318 Online
Need help? Post your question and get tips & solutions from a community of 446,368 IT Pros & Developers. It's quick & easy.

# How to extract bytes from long?

 P: n/a 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 Nov 13 '05 #1
44 Replies

 P: n/a 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" Nov 13 '05 #2

 P: n/a On Wed, 15 Oct 2003 01:59:04 -0700, RB wrote: How to extract bytes from long, starting from the last byte? #include 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 Nov 13 '05 #3

 P: n/a 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 int main(void) { long val=0x12345678; printf("0x%x\n",val >> 16 & 0xff ); return 0; } Regards, Ed. Nov 13 '05 #4

 P: n/a 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 #include 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 Nov 13 '05 #5

 P: n/a 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 #include 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 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 Nov 13 '05 #6

 P: n/a ri********@yahoo.com (RB) wrote in message news:<3a*************************@posting.google.c om>... 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. Nov 13 '05 #7

 P: n/a pete wrote in message news:<3F***********@mindspring.com>... 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 #include 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 Nov 13 '05 #8

 P: n/a 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 #include 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 (cb********@yahoo.com) (cb********@worldnet.att.net) Available for consulting/temporary embedded and systems. USE worldnet address! Nov 13 '05 #9

 P: n/a pete wrote in message news:<3F***********@mindspring.com>... 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 Nov 13 '05 #10

 P: n/a op*****@yahoo.com (Samuel Barber) wrote in message news:<37**************************@posting.google. com>... pete wrote in message news:<3F***********@mindspring.com>... 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 Nov 13 '05 #11

 P: n/a Peter Nilsson wrote: pete wrote in message news:<3F***********@mindspring.com>... 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 #include 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 Nov 13 '05 #12

 P: n/a ai***@acay.com.au (Peter Nilsson) wrote in message news:<63**************************@posting.google. com>... op*****@yahoo.com (Samuel Barber) wrote in message news:<37**************************@posting.google. com>... pete wrote in message news:<3F***********@mindspring.com>... 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 Nov 13 '05 #13

 P: n/a 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 #include 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 Nov 13 '05 #14

 P: n/a Samuel Barber wrote: ai***@acay.com.au (Peter Nilsson) wrote in message news:<63**************************@posting.google. com>... op*****@yahoo.com (Samuel Barber) wrote in message news:<37**************************@posting.google. com>... pete wrote in message news:<3F***********@mindspring.com>... > 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 Nov 13 '05 #15

 P: n/a On Fri, 17 Oct 2003 02:44:03 +0000, pete wrote: Samuel Barber wrote: ai***@acay.com.au (Peter Nilsson) wrote in message news:<63**************************@posting.google. com>... > op*****@yahoo.com (Samuel Barber) wrote in message news:<37**************************@posting.google. com>... > > pete wrote in message news:<3F***********@mindspring.com>... > > > 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. Nov 13 '05 #16

 P: n/a pete wrote in message news:<3F***********@mindspring.com>... Samuel Barber wrote: ai***@acay.com.au (Peter Nilsson) wrote in message news:<63**************************@posting.google. com>... op*****@yahoo.com (Samuel Barber) wrote in message news:<37**************************@posting.google. com>... > pete wrote in message news:<3F***********@mindspring.com>... > > 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 Nov 13 '05 #17

 P: n/a On Fri, 16 Oct 2003, Samuel Barber wrote: pete wrote in message news:<3F***********@mindspring.com>... Samuel Barber wrote: (Peter Nilsson) wrote... > Samuel Barber wrote... > > pete wrote in message news:<3F***********@mindspring.com>... > > > > > > 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]; ++i)'s and 'while (*s++ = *t++)'s; if a simple -1 throws you, then you're in trouble. :-) -Arthur Nov 13 '05 #18

 P: n/a On Thu, 16 Oct 2003 23:53:05 -0700, Samuel Barber wrote: pete wrote in message news:<3F***********@mindspring.com>... Samuel Barber wrote: > > ai***@acay.com.au (Peter Nilsson) wrote in message news:<63**************************@posting.google. com>... > > op*****@yahoo.com (Samuel Barber) wrote in message news:<37**************************@posting.google. com>... > > > pete wrote in message news:<3F***********@mindspring.com>... > > > > 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. Nov 13 '05 #19

 P: n/a 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 Nov 13 '05 #20

 P: n/a Jirka Klaue wrote: .... (uc)-1 == (uc)(0 - 1) == (uc)(UINT_MAX + 1 - 1) == (uc)(UINT_MAX) == UCHAR_MAX s/UI/I/g Jirka Nov 13 '05 #21

 P: n/a op*****@yahoo.com (Samuel Barber) wrote in message news:<37**************************@posting.google. com>... pete wrote in message news:<3F***********@mindspring.com>... -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). (Quoting myself) Please disregard this part of my reply. I misinterpreted what Pete was saying. Sam Nov 13 '05 #22

 P: n/a "Arthur J. O'Dwyer" wrote in message news:... Samuel Barber wrote: 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?) The C bitwise operators are &, |, ^, and ~ (>> and << are also included in this catagory, although bitwise is a misnomer in the case of shifts). "Trap" in the context of this discussion seems to mean "detect an illegal value"; well, there are only two values of interest to bitwise operators (0 and 1), and they are both legal. So how can it trap? Sam Nov 13 '05 #23

 P: n/a Sheldon Simms wrote in message news:... 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. Okay, but if we are to believe this hocus pocus, there is no way to avoid the hypothetical trapping. It makes no difference whether you use (unsigned char)-1, (unsigned char)~0, or UCHAR_MAX, since they all evaluate to the same thing. All are equally right or equally wrong. Sam Nov 13 '05 #24

 P: n/a op*****@yahoo.com (Samuel Barber) wrote: "Arthur J. O'Dwyer" wrote in message news:... > > Samuel Barber wrote: > 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?)The C bitwise operators are &, |, ^, and ~ (>> and << are alsoincluded in this catagory, although bitwise is a misnomer in the caseof shifts). Not from the standard's POV. In fact, they are referred to as "bitwise shift operators" explicitly. "Trap" in the context of this discussion seems to mean"detect an illegal value"; well, there are only two values of interestto bitwise operators (0 and 1), and they are both legal. So how can ittrap? Read C99 6.2.6.2, Sheldon Simms already quoted the relevant parts in reply to your other post. Regards -- Irrwahn (ir*******@freenet.de) Nov 13 '05 #25

 P: n/a "Arthur J. O'Dwyer" schrieb im Newsbeitrag news:Pi**********************************@unix48.a ndrew.cmu.edu... 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). Why should ~0 trap??? it results in the 1's complement of 0 which means all bits are 1's. Padding bits are not affected by this operation, however the values of padding bits should never be of your interest. A Trap representation can *only* be generated when manipulating the value using pointers which aren't the type of the value or doesn't start at the exact address of the value. Wrong usage of an union can also result in a Trap representation. But all arithmetic or bitwise operations cannot result in a trap-representation. -- cody [Freeware, Games and Humor] www.deutronium.de.vu || www.deutronium.tk Nov 13 '05 #27

 P: n/a pete wrote: 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 > #include > > 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. You were not extracting bytes. You were extracting 8 bit quantities, least significant part first. In other words you are expressing the _value_ in base 256, so why not say so in the code? If the compiler knows that it can improve the code by using shifts, it may do so. -- Chuck F (cb********@yahoo.com) (cb********@worldnet.att.net) Available for consulting/temporary embedded and systems. USE worldnet address! Nov 13 '05 #28

 P: n/a On Fri, 17 Oct 2003, Jirka Klaue wrote: 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. Augh! I do that every time! Thanks. (uc)-1 == (uc)(0 - 1) == (-1+UCHAR_MAX+1) == UCHAR_MAX -Arthur Nov 13 '05 #29

 P: n/a On Fri, 17 Oct 2003, cody wrote: "Arthur J. O'Dwyer" schrieb... 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). Why should ~0 trap??? it results in the 1's complement of 0 which means all bits are 1's ....which may be a trap representation on a ones'-complement architecture. Padding bits are not affected by this operation, however the values of padding bits should never be of your interest. Well, technically padding bits *might* be affected by the ~ operation, but the effect on the padding bits alone cannot create a trap representation -- the system has to remember to do the Right Thing with them in this case. A trap representation can *only* be generated when manipulating the value using pointers which aren't the type of the value or doesn't start at the exact address of the value. Wrong. Signed integer overflow may create a trap value, for instance. Wrong usage of an union can also result in a trap representation. But all arithmetic or bitwise operations cannot result in a trap representation. Wrong. -Arthur Nov 13 '05 #30

 P: n/a On Fri, 17 Oct 2003 20:06:45 +0200, cody wrote: "Arthur J. O'Dwyer" schrieb im Newsbeitrag news:Pi**********************************@unix48.a ndrew.cmu.edu... 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). Why should ~0 trap??? it results in the 1's complement of 0 which means all bits are 1's. Padding bits are not affected by this operation, however the values of padding bits should never be of your interest. A Trap representation can *only* be generated when manipulating the value using pointers which aren't the type of the value or doesn't start at the exact address of the value. Wrong usage of an union can also result in a Trap representation. But all arithmetic or bitwise operations cannot result in a trap-representation. Go back and read the whole thread Nov 13 '05 #31

 P: n/a "pete" wrote in message news:3F***********@mindspring.com... Peter Nilsson wrote: .... UB if sizeof(long) == 1. No. If sizeof(long) == 1, then the loop doesn't execute. My bad. -- Peter Nov 13 '05 #32

 P: n/a CBFalconer wrote: pete wrote: 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 > > #include > > > > 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. You were not extracting bytes. You were extracting 8 bit quantities, least significant part first. In other words you are expressing the _value_ in base 256, so why not say so in the code? I don't know what you're talking about. Which code do you think is mine? -- pete Nov 13 '05 #33

 P: n/a Chris Torek wrote in message news:... The section quoted above (along with others) define how the abtract machine is to work. In the abstract machine, writing: ~0 means: - make an int with the value 0 - now, flip all the bits This process *can* give rise to a "trap representation" on a ones' complement machine. Thanks, I get it now. The correct usage is therefore ~0u or ~0U. Sam Nov 13 '05 #34

 P: n/a op*****@yahoo.com (Samuel Barber) wrote in message news:<37**************************@posting.google. com>... pete wrote in message news:<3F***********@mindspring.com>... Samuel Barber wrote: ai***@acay.com.au (Peter Nilsson) wrote in message news:<63**************************@posting.google. com>... > op*****@yahoo.com (Samuel Barber) wrote in message news:<37**************************@posting.google. com>... > > pete wrote in message news:<3F***********@mindspring.com>... > > > 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. I was wrong about everything. ~0 is "wrong" (in terms of the abstract C machine); the correct expression is ~0u or ~0U. Sam Nov 13 '05 #35

 P: n/a "cody" writes: "Arthur J. O'Dwyer" schrieb im Newsbeitrag news:Pi**********************************@unix48.a ndrew.cmu.edu... 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). Why should ~0 trap??? it results in the 1's complement of 0 which means all bits are 1's. Padding bits are not affected by this operation, however the values of padding bits should never be of your interest. A Trap representation can *only* be generated when manipulating the value using pointers which aren't the type of the value or doesn't start at the exact address of the value. Wrong usage of an union can also result in a Trap representation. But all arithmetic or bitwise operations cannot result in a trap-representation. This is not true. You should read the relevant portions of the standard before making such assertions. -Micah Nov 13 '05 #36

 P: n/a "Arthur J. O'Dwyer" writes: On Fri, 17 Oct 2003, cody wrote: "Arthur J. O'Dwyer" schrieb... 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). Why should ~0 trap??? it results in the 1's complement of 0 which means all bits are 1's ...which may be a trap representation on a ones'-complement architecture. Padding bits are not affected by this operation, however the values of padding bits should never be of your interest. Well, technically padding bits *might* be affected by the ~ operation, but the effect on the padding bits alone cannot create a trap representation -- the system has to remember to do the Right Thing with them in this case. I don't believe this is true. Can you back this up with a quote from the standard? I cannot remember any instance where the standard says this can't be: and I can think of a specific spot where the standard says (non-normatively) that this *can* be (see footnote 45 to 6.2.6.2#5). The lack of exclusion means it certainly is possible. -Micah Nov 13 '05 #37

 P: n/a On Sat, 18 Oct 2003, Micah Cowan wrote: "Arthur J. O'Dwyer" writes: On Fri, 17 Oct 2003, cody wrote: Why should ~0 trap??? it results in the 1's complement of 0 which means all bits are 1's ...which may be a trap representation on a ones'-complement architecture. Padding bits are not affected by this operation, however the values of padding bits should never be of your interest. Well, technically padding bits *might* be affected by the ~ operation, but the effect on the padding bits alone cannot create a trap representation -- the system has to remember to do the Right Thing with them in this case. I don't believe this is true. Can you back this up with a quote from the standard? From N869, section 6.2.6.2, footnote 39: Some combinations of padding bits might generate trap representations, for example, if one padding bit is a parity bit. Regardless, no arithmetic operation on valid ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ values can generate a trap representation other than as ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ part of an exception such as an overflow, and this cannot occur with unsigned types. All other combinations of padding bits are alternative object representations of the value specified by the value bits. (The index to N869 clearly puts "bitwise operators" under "arithmetic operators," even if the text doesn't explicitly say so.) This is obviously the Right Thing for the standard to say, too, since if padding bits' values *could* create trap representations out of thin air, how could programmers on those platforms ever compute anything? I cannot remember any instance where the standard says this can't be: and I can think of a specific spot where the standard says (non-normatively) that this *can* be (see footnote 45 to 6.2.6.2#5). N869 doesn't have a 6.2.6.2#5. Could you post that paragraph and footnote, please? -Arthur Nov 13 '05 #38

 P: n/a Micah Cowan wrote: "Arthur J. O'Dwyer" writes: N869 doesn't have a 6.2.6.2#5. Could you post that paragraph and footnote, please?The paragraph doesn't tell you anything you don't know (it's gotto be in N869) Chapter 6.2.6.2: C99 final N869 #1 --> #1 #2 --> #2 #3 --> -- #4 --> -- #5 --> #3 #6 --> #4 Regards -- Irrwahn (ir*******@freenet.de) Nov 13 '05 #40

 P: n/a Samuel Barber wrote: The correct usage is therefore ~0u or ~0U. Bitwise operators are usually used on unsigned types. Bitwise operators return implementation defined values or cause undefined behavior, on signed types, if the sign bit is set or if the operation attempts to set it. -- pete Nov 13 '05 #41

 P: n/a CBFalconer wrote: Peter Shaggy Haywood wrote: CBFalconer was jivin' on Thu, 16 Oct 2003 06:07:04 GMT 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. Why not just: puts("0x78, 0x56, 0x34, 0x12"); ? That's portable too. Hardly. You are making huge assumptions about the sizes of long and unsigned char. Who says sizeof(long) is 8? And who says a byte is 8 bits? These assumptions are evident in your code, and are decidedly non-portable. But it is, if you say the object is to emit 8 pairs of hex digits, Where did you get the idea that the object, is to emit 8 pairs of hex digits? Nothing like that, has even been remotely suggested anywhere previously in this thread. with the first representing the least significant bits. This gives a fixed output field. Conceded, it truncates anything past 64 bits in an unsigned long. If the objective is to dump all digits, and ignore the more significant zeroes, you can simply exit the loop when the value becomes zero. In both cases the technique is independant of CHAR_BIT and sizeof(long) and, most important, independent of endianess. The technique is also independant of, and irrelevant to, the the subject line of this thread. OP gave an example which suggested 8 bits per byte, but the question was "How to extract bytes from long?" -- pete Nov 13 '05 #42

 P: n/a pete wrote: CBFalconer wrote: Peter Shaggy Haywood wrote: CBFalconer was jivin' on Thu, 16 Oct 2003 06:07:04 GMT > 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. .... snip ... Hardly. You are making huge assumptions about the sizes of long and unsigned char. Who says sizeof(long) is 8? And who says a byte is 8 bits? These assumptions are evident in your code, and are decidedly non-portable. But it is, if you say the object is to emit 8 pairs of hex digits, Where did you get the idea that the object, is to emit 8 pairs of hex digits? Nothing like that, has even been remotely suggested anywhere previously in this thread. From the original post, quoted below: 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 Granted, it is not definitive, but is how I interpreted it. -- Chuck F (cb********@yahoo.com) (cb********@worldnet.att.net) Available for consulting/temporary embedded and systems. USE worldnet address! Nov 13 '05 #43

 P: n/a CBFalconer wrote: pete wrote: CBFalconer wrote: Peter Shaggy Haywood wrote: > CBFalconer was jivin' on Thu, 16 Oct 2003 06:07:04 GMT > > > 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. .... snip ... But it is, if you say the object is to emit 8 pairs of hex digits, Where did you get the idea that the object, is to emit 8 pairs of hex digits? Nothing like that, has even been remotely suggested anywhere previously in this thread.From the original post, quoted below: 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 Granted, it is not definitive, but is how I interpreted it. That's only 4 pairs of hex digits. This is your output: 78 56 34 12 0 0 0 0 -- pete Nov 13 '05 #44

 P: n/a Samuel Barber wrote: op*****@yahoo.com (Samuel Barber) wrote in message news:<37**************************@posting.google. com>... pete wrote in message news:<3F***********@mindspring.com>... Samuel Barber wrote: > > ai***@acay.com.au (Peter Nilsson) wrote in message news:<63**************************@posting.google. com>... > > op*****@yahoo.com (Samuel Barber) wrote in message news:<37**************************@posting.google. com>... > > > pete wrote in message news:<3F***********@mindspring.com>... > > > > 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. I was wrong about everything. ~0 is "wrong" (in terms of the abstract C machine); the correct expression is ~0u or ~0U. (unsigned char)~0u would work instead of (unsigned char)-1, in the above code example, but for the general case of casting a constant, to get an object with all bits set, (unsigned cast)-1 is more versatile than (unsigned cast)~0u. ((size_t)-1) and ((long unsigned)-1), are both unsigned values with all bits set. ((size_t)~0u) and ((long unsigned)~0u), may or may not have all bits set, depending on whether the width of the respective types, is greater than the width of unsigned. -- pete Nov 13 '05 #45

### This discussion thread is closed

Replies have been disabled for this discussion.