|
|
|
|
||||||
![]() |
|
|
LinkBack | Outils de la discussion |
|
|
#1 |
|
Messages: n/a
Hébergeur: |
I have a byte called "x". I want byte "y" to be the complement of "x" (i.e. all the bits flipped). Initially I wrote: char unsigned x, y; ... x = 72; y = ~x; But then I thought that the following might happen on your average system (CHAR_BIT == 8, sizeof(int) == 4): 1) x is promoted to signed int. 2) The complement is take of this signed int. 3) This signed int is then converted to an unsigned char Am I right in thinking that this is what will happen? If so, would I be wise to do the following instead: y = ~(unsigned)x; -- Tomás Ó hÉilidhe |
|
|
|
#2 |
|
Messages: n/a
Hébergeur: |
On Jan 31, 12:45 pm, t...@lavabit.com wrote:
> I have a byte called "x". I want byte "y" to be the complement of > "x" (i.e. all the bits flipped). > > Initially I wrote: > > char unsigned x, y; > > ... > > x = 72; > > y = ~x; > > But then I thought that the following might happen on your average > system (CHAR_BIT == 8, sizeof(int) == 4): > > 1) x is promoted to signed int. That won't happend, therefore the rest of your thoughts is false. Your code is perfectly valid. |
|
|
|
#3 |
|
Messages: n/a
Hébergeur: |
On Jan 31, 10:48am, vipps...@gmail.com wrote:
> > 1) x is promoted to signed int. > > That won't happend, therefore the rest of your thoughts is false. > Your code is perfectly valid. My understanding was as follows: "If you're dealing with an integer type smaller than int, then it must undergo promotion before you can perform any operations on it." -- Tomás Ó hÉilidhe |
|
|
|
#4 |
|
Messages: n/a
Hébergeur: |
toe@lavabit.com wrote:
> I have a byte called "x". I want byte "y" to be the complement of > "x" (i.e. all the bits flipped). > > Initially I wrote: > > char unsigned x, y; > > ... > > x = 72; > > y = ~x; > > But then I thought that the following might happen on your average > system (CHAR_BIT == 8, sizeof(int) == 4): > > 1) x is promoted to signed int. > 2) The complement is take of this signed int. > 3) This signed int is then converted to an unsigned char That's right, under your assumptions. On "exotic" machines where UCHAR_MAX > INT_MAX (for example, on hardware where all of char, short, and int are 16 bits wide), then x promotes to an unsigned int instead of to an int in step 1. Also see vippstar's response: It's wrong. > Am I right in thinking that this is what will happen? If so, would I > be wise to do the following instead: > > y = ~(unsigned)x; Yes, this will work on both "exotic" and "humdrum" machines. -- Eric.Sosman@sun.com |
|
|
|
#5 |
|
Messages: n/a
Hébergeur: |
Eric Sosman:
>> 1) x is promoted to signed int. >> 2) The complement is take of this signed int. >> 3) This signed int is then converted to an unsigned char > > That's right, under your assumptions. On "exotic" machines > where UCHAR_MAX > INT_MAX (for example, on hardware where all > of char, short, and int are 16 bits wide), then x promotes to > an unsigned int instead of to an int in step 1. So just to confirm if I'm thinking right. We start off with: char unsigned x, y; x = 0xf0; y = ~x; What we _want_ this code to do is to give us the value 0x0f for y (i.e. the complement of x). However what _could_ happen is: 1) x is promoted to signed int. => Now we have a signed int with the value 0xf0 2) The complement is taken of this signed int. => Now we have some other number that is negative. The exact number depends on the number system in use (e.g. sign-magnitude), and also the amount of bits in an int. 3) The signed int is converted to an unsigned char. => This process is well-defined, but we don't know what signed value we have. Therefore, it is my assumption that will not give the desired behaviour on every implementation of the Standard -- we could get something totally different from 0x0f as an answer (even on an 8-bit-byte system). That sound right? -- Tomás Ó hÉilidhe |
|
|
|
#6 |
|
Messages: n/a
Hébergeur: |
Tomás Ó hÉilidhe wrote:
> Eric Sosman: > >>> 1) x is promoted to signed int. >>> 2) The complement is take of this signed int. >>> 3) This signed int is then converted to an unsigned char >> That's right, under your assumptions. On "exotic" machines >> where UCHAR_MAX > INT_MAX (for example, on hardware where all >> of char, short, and int are 16 bits wide), then x promotes to >> an unsigned int instead of to an int in step 1. > > > So just to confirm if I'm thinking right. We start off with: > > char unsigned x, y; > > x = 0xf0; > > y = ~x; > > What we _want_ this code to do is to give us the value 0x0f for y (i.e. > the complement of x). However what _could_ happen is: > > 1) x is promoted to signed int. > > => Now we have a signed int with the value 0xf0 > > 2) The complement is taken of this signed int. > > => Now we have some other number that is negative. The exact number > depends on the number system in use (e.g. sign-magnitude), and > also the amount of bits in an int. > > 3) The signed int is converted to an unsigned char. > > => This process is well-defined, but we don't know what signed > value we have. > > Therefore, it is my assumption that will not give the desired behaviour > on every implementation of the Standard -- we could get something > totally different from 0x0f as an answer (even on an 8-bit-byte system). > > That sound right? Sounds right to me. The list of potential negative values is long but "sparse:" two's complement and ones' complement give -241 and -240, respectively, while signed magnitude gives one of -0x7f0f, -0xff0f, -0x1ff0f, ... depending on the number of value bits in an int. -- Eric.Sosman@sun.com |
|
|
|
#7 |
|
Messages: n/a
Hébergeur: |
On Jan 31, 6:22 pm, Eric Sosman <Eric.Sos...@sun.com> wrote:
> t...@lavabit.com wrote: > > I have a byte called "x". I want byte "y" to be the complement of > > "x" (i.e. all the bits flipped). > > > Initially I wrote: > > > char unsigned x, y; > > > ... > > > x = 72; > > > y = ~x; > > > But then I thought that the following might happen on your average > > system (CHAR_BIT == 8, sizeof(int) == 4): > > > 1) x is promoted to signed int. > > 2) The complement is take of this signed int. > > 3) This signed int is then converted to an unsigned char > > That's right, under your assumptions. On "exotic" machines > where UCHAR_MAX > INT_MAX (for example, on hardware where all > of char, short, and int are 16 bits wide), then x promotes to > an unsigned int instead of to an int in step 1. > > Also see vippstar's response: It's wrong. Ah, I apologise, just something i am not sure about, char unsigned x, y; means unsigned char x, 'plain' char y? |
|
|
|
#8 |
|
Messages: n/a
Hébergeur: |
vippstar@gmail.com wrote:
> On Jan 31, 6:22 pm, Eric Sosman <Eric.Sos...@sun.com> wrote: >> t...@lavabit.com wrote: >> > I have a byte called "x". I want byte "y" to be the complement of >> > "x" (i.e. all the bits flipped). >> >> > Initially I wrote: >> >> > char unsigned x, y; >> >> > ... >> >> > x = 72; >> >> > y = ~x; >> >> > But then I thought that the following might happen on your average >> > system (CHAR_BIT == 8, sizeof(int) == 4): >> >> > 1) x is promoted to signed int. >> > 2) The complement is take of this signed int. >> > 3) This signed int is then converted to an unsigned char >> >> That's right, under your assumptions. On "exotic" machines >> where UCHAR_MAX > INT_MAX (for example, on hardware where all >> of char, short, and int are 16 bits wide), then x promotes to >> an unsigned int instead of to an int in step 1. >> >> Also see vippstar's response: It's wrong. > Ah, I apologise, just something i am not sure about, char unsigned x, > y; means unsigned char x, 'plain' char y? No, it's equivalent to: unsigned char x; unsigned char y; |
|
|
|
#9 |
|
Messages: n/a
Hébergeur: |
vippstar@gmail.com wrote:
> > Ah, I apologise, just something i am not sure about, char unsigned x, > y; means unsigned char x, 'plain' char y? `char unsigned' means the same thing as `unsigned char'; the order of the keywords in a multi-keyword type specifier doesn't matter. So `char unsigned x, y;' means the same thing as `unsigned char x, y;' and gives both x and y the same type. Win pocket money by writing `long int signed long x;' or `double long y;' and betting the boys at the bar that it's legal C. -- Eric.Sosman@sun.com |
|
|
|
#10 |
|
Messages: n/a
Hébergeur: |
On Thu, 31 Jan 2008 02:48:28 -0800 (PST), vippstar@gmail.com wrote in
comp.lang.c: > On Jan 31, 12:45 pm, t...@lavabit.com wrote: > > I have a byte called "x". I want byte "y" to be the complement of > > "x" (i.e. all the bits flipped). > > > > Initially I wrote: > > > > char unsigned x, y; > > > > ... > > > > x = 72; > > > > y = ~x; > > > > But then I thought that the following might happen on your average > > system (CHAR_BIT == 8, sizeof(int) == 4): > > > > 1) x is promoted to signed int. > That won't happend, therefore the rest of your thoughts is false. > Your code is perfectly valid. No, your correction is false. 'x' must be promoted to either signed or unsigned int before the bitwise inversion operator is applies. In a system with CHAR_BIT is 8, a signed int must be able to hold all possible values of unsigned char, so 'x' is indeed promoted to signed int. -- Jack Klein Home: http://JK-Technology.Com FAQs for comp.lang.c http://c-faq.com/ comp.lang.c++ http://www.parashift.com/c++-faq-lite/ alt.comp.lang.learn.c-c++ http://www.club.cc.cmu.edu/~ajo/docs/FAQ-acllc.html |
|
![]() |
| Outils de la discussion | |
|
|