Compare every bit of char versus unsigned char

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

1. jamxGuest

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

2. Robin HaighGuest

"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

3. ranjmisGuest

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

cheers
- Ranjeet

ranjmis, Mar 7, 2006
4. John FGuest

"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
5. jamxGuest

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
6. Ben PfaffGuest

"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
7. peteGuest

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
8. jamxGuest

Thanks pete !!! this way it works perfect ;-)

jamx, Mar 7, 2006
9. Default UserGuest

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

Default User, Mar 7, 2006
10. Keith ThompsonGuest

"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

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
11. 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
12. Barry SchwarzGuest

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