Compare every bit of char versus unsigned char

J

jamx

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
 
R

Robin Haigh

jamx said:
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)
 
R

ranjmis

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

cheers
- Ranjeet
 
J

John F

Robin Haigh said:
jamx said:
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)

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.
 
J

jamx

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.
 
B

Ben Pfaff

jamx said:
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.
 
P

pete

jamx said:
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)
 
D

Default User

ranjmis said:
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
 
K

Keith Thompson

jamx said:
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];
?
 
E

ena8t8si

jamx said:
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.
 
B

Barry Schwarz

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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top