Compare every bit of char versus unsigned char

Discussion in 'C Programming' started by jamx, Mar 7, 2006.

  1. jamx

    jamx Guest

    I need to compare the following values:

    char buf[3];

    /* buf is filled using COMport here... */

    if (buf[0] == 0x85) {
    /* do something */
    }

    But since 0x85 is bigger then char's maximum value this won't really
    work. So how can i compare all bits of a char with a other byte, like
    0x85 in this example???

    I was thinking about casting the char to unsigned char, in the
    if-statement. But im not sure if that will work flawlessly...

    Greetings, Frank
    jamx, Mar 7, 2006
    #1
    1. Advertising

  2. jamx

    Robin Haigh Guest

    "jamx" <> wrote in message
    news:...
    > I need to compare the following values:
    >
    > char buf[3];
    >
    > /* buf is filled using COMport here... */
    >
    > if (buf[0] == 0x85) {
    > /* do something */
    > }
    >
    > But since 0x85 is bigger then char's maximum value this won't really
    > work. So how can i compare all bits of a char with a other byte, like
    > 0x85 in this example???
    >
    > I was thinking about casting the char to unsigned char, in the
    > if-statement. But im not sure if that will work flawlessly...


    *(unsigned char *)buf examines the bit pattern. interpreted as base-2.
    (unsigned char)buf[0] yields 256 - buf[0] when buf[0] is negative, since
    we're assuming 8 bits. The result is the same.

    Except if you have a machine where the arithmetic is not 2's-complement but
    the native char type is signed in spite of that. If you have such a
    machine, run away very fast. Do not attempt to program it. (In any case,
    the question can't be answered portably for such a machine, it would depend
    on what conversion was involved in filling the array from the input source)

    --
    RSH
    Robin Haigh, Mar 7, 2006
    #2
    1. Advertising

  3. jamx

    ranjmis Guest

    define buf[..] as 'unsigned char' instead of 'char', then it should
    work

    cheers
    - Ranjeet
    ranjmis, Mar 7, 2006
    #3
  4. jamx

    John F Guest

    "Robin Haigh" wrote:
    >
    > "jamx" <> wrote:
    >> I need to compare the following values:
    >>
    >> char buf[3];
    >>
    >> /* buf is filled using COMport here... */
    >>
    >> if (buf[0] == 0x85) {
    >> /* do something */
    >> }
    >>
    >> But since 0x85 is bigger then char's maximum value this won't
    >> really
    >> work. So how can i compare all bits of a char with a other byte,
    >> like
    >> 0x85 in this example???
    >>
    >> I was thinking about casting the char to unsigned char, in the
    >> if-statement. But im not sure if that will work flawlessly...

    >
    > *(unsigned char *)buf examines the bit pattern. interpreted as
    > base-2.
    > (unsigned char)buf[0] yields 256 - buf[0] when buf[0] is negative,
    > since
    > we're assuming 8 bits. The result is the same.
    >
    > Except if you have a machine where the arithmetic is not
    > 2's-complement but
    > the native char type is signed in spite of that. If you have such a
    > machine, run away very fast. Do not attempt to program it. (In any
    > case,
    > the question can't be answered portably for such a machine, it would
    > depend
    > on what conversion was involved in filling the array from the input
    > source)
    >
    > --
    > RSH


    I see no reason why

    if( !( buf[0] ^ 0x85 )) {/*arbitrary code here*/}

    shouldn't work in any case...

    Maybe I'm missing some tiny detail here ... could be.

    regards
    John
    --
    You can have it:

    Quick.
    Accurate.
    Inexpensive.

    Pick two.
    John F, Mar 7, 2006
    #4
  5. jamx

    jamx Guest

    I just keep getting this warning when i use ( !(buf[0] ^ 0x85)) :

    comparison is always true due to limited range of data type

    and when i use: if ((*(unsigned char *)cmd_reply[0] == 0x41)) i get
    this warning:

    cast to pointer from integer of different size

    It might work in some cases.. but compiling with these kinda warnings
    isn't really my goal. And i also cannot change buf[] to an unsigned
    char since my COM object requires char.
    jamx, Mar 7, 2006
    #5
  6. jamx

    Ben Pfaff Guest

    "jamx" <> writes:

    > I just keep getting this warning when i use ( !(buf[0] ^ 0x85)) :
    >
    > comparison is always true due to limited range of data type


    Presumably buf[0] is a char and you are in a signed character
    environment. In that case, the buf[0] that you're thinking of as
    having value 0x85 actually has value -123 (in a 2's complement
    environment, if I did the math right). As an int, which it will
    normally be promoted to, this is bit pattern 0xffffff85 (in a
    32-bit, 2's complement environment). 0xffffff85 ^ 0x85 is
    0xffffff00, not 0.

    I think this analysis is correct, but I always find this a
    confusing area of standard C. I hope my errors, if any, will be
    corrected quickly.
    --
    "I ran it on my DeathStation 9000 and demons flew out of my nose." --Kaz
    Ben Pfaff, Mar 7, 2006
    #6
  7. jamx

    pete Guest

    jamx wrote:
    >
    > I just keep getting this warning when i use ( !(buf[0] ^ 0x85)) :
    >
    > comparison is always true due to limited range of data type
    >
    > and when i use: if ((*(unsigned char *)cmd_reply[0] == 0x41)) i get
    > this warning:
    >
    > cast to pointer from integer of different size
    >
    > It might work in some cases.. but compiling with these kinda warnings
    > isn't really my goal. And i also cannot change buf[] to an unsigned
    > char since my COM object requires char.


    You didn't do it right.

    if (((unsigned char *)cmd_reply)[0] == 0x41)

    --
    pete
    pete, Mar 7, 2006
    #7
  8. jamx

    jamx Guest

    Thanks pete !!! this way it works perfect ;-)
    jamx, Mar 7, 2006
    #8
  9. jamx

    Default User Guest

    ranjmis wrote:

    > define buf[..] as 'unsigned char' instead of 'char', then it should
    > work


    What should work? It's difficult to tell what you are talking about.
    See below.



    Brian
    --
    Please quote enough of the previous message for context. To do so from
    Google, click "show options" and use the Reply shown in the expanded
    header.
    Default User, Mar 7, 2006
    #9
  10. "jamx" <> writes:
    > I need to compare the following values:
    >
    > char buf[3];
    >
    > /* buf is filled using COMport here... */
    >
    > if (buf[0] == 0x85) {
    > /* do something */
    > }
    >
    > But since 0x85 is bigger then char's maximum value this won't really
    > work. So how can i compare all bits of a char with a other byte, like
    > 0x85 in this example???
    >
    > I was thinking about casting the char to unsigned char, in the
    > if-statement. But im not sure if that will work flawlessly...


    Plain char may be either signed or unsigned. Apparently it's signed
    in your environment.

    Is there any reason you can't just declare buf as
    unsigned char buf[3];
    ?

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
    Keith Thompson, Mar 7, 2006
    #10
  11. jamx

    Guest

    jamx wrote:
    > I need to compare the following values:
    >
    > char buf[3];
    >
    > /* buf is filled using COMport here... */
    >
    > if (buf[0] == 0x85) {
    > /* do something */
    > }
    >
    > But since 0x85 is bigger then char's maximum value this won't really
    > work. So how can i compare all bits of a char with a other byte, like
    > 0x85 in this example???
    >
    > I was thinking about casting the char to unsigned char, in the
    > if-statement. But im not sure if that will work flawlessly...


    It depends on what your assumptions are about where the
    negative character values come from, and whether the
    representation is known to be twos complement or not.
    The comparisons

    if ((unsigned char)buf[0] == 0x85) {

    if (((unsigned char*)buf)[0] == 0x85) {

    do the same thing for twos complement, but not for
    the other representations. Depending on how values
    get from the wire on the COM port into the buffer,
    you should use one of these or the other.
    , Mar 8, 2006
    #11
  12. On 7 Mar 2006 09:45:52 -0800, "jamx" <> wrote:

    >I just keep getting this warning when i use ( !(buf[0] ^ 0x85)) :
    >
    >comparison is always true due to limited range of data type
    >
    >and when i use: if ((*(unsigned char *)cmd_reply[0] == 0x41)) i get
    >this warning:
    >
    >cast to pointer from integer of different size


    You probably want an & in front of cmd_reply.

    >
    >It might work in some cases.. but compiling with these kinda warnings
    >isn't really my goal. And i also cannot change buf[] to an unsigned
    >char since my COM object requires char.



    Remove del for email
    Barry Schwarz, Mar 12, 2006
    #12
    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. Steffen Fiksdal

    void*, char*, unsigned char*, signed char*

    Steffen Fiksdal, May 8, 2005, in forum: C Programming
    Replies:
    1
    Views:
    579
    Jack Klein
    May 9, 2005
  2. Alex Vinokur
    Replies:
    9
    Views:
    787
    James Kanze
    Oct 13, 2008
  3. Replies:
    3
    Views:
    417
    James Kanze
    Nov 19, 2008
  4. pozz
    Replies:
    12
    Views:
    738
    Tim Rentsch
    Mar 20, 2011
  5. Paul Butcher
    Replies:
    12
    Views:
    708
    Gary Wright
    Nov 28, 2007
Loading...

Share This Page