Velocity Reviews > unsigned and signed 0

# unsigned and signed 0

Richard Bos
Guest
Posts: n/a

 09-22-2003
Sona <(E-Mail Removed)> wrote:

> What is the difference between a signed 0x00 (NULL, or 0) and an
> unsigned 0x00? Can there be one?

First, let's get rid of all the misconceptions.

To begin with, 0x00 is always signed. It's a hexadecimal integral
constant with the value 0, unsuffixed. This means that it is an int, and
an int is signed.
You probably meant "an object with all bits zero". Because of the
previous point, 0x00 is not a good way to express this, but I'll assume
you meant this anyway for the following points.

The second point is that NULL is a null pointer constant, not a null
pointer; the difference is important. A null pointer constant is a part
of your source code, not an object. It can be 0, or (void*)0, or
('-'-'-'), or (void *)(1 - sizeof (char) ), or anything equivalent. It
has no bit pattern as such; but in a pointer context, it is converted to
a null pointer, which has.
A null pointer, then, is not guaranteed to have the bit pattern "all
zeroes". It often does; but this is not required. All that's required is
that it is a distinct pointer that does not point at any valid object.
Comparing a null pointer to 0 works because the 0, in this pointer
context, is converted to another null pointer, not because the null
pointer is in any way compared to an integral 0.

Third, it doesn't matter. Signed integers must use the same
representation for non-negative values as their unsigned counterparts;
and this must be a pure binary representation. Moreover, all comparisons
go by value, so if you compare 0x00 with 0x00u, they must compare equal.

> If I do the following:
>
> char var;
> var = 0x00;
>
> what should var hold?

The value 0. An int with the value 0 is assigned to a char, and since
that char can hold this value, the result should be as expected.

Note that, since we don't know whether chars are signed or unsigned on
your system, we don't know whether it's a signed or unsigned zero,
either. Note also that, as above, it shouldn't matter a jot.

> and if it was an unsigned char, what should it hold then?

The value 0, in an unsigned char object.

Richard

Sona
Guest
Posts: n/a

 09-22-2003
Hi,

What is the difference between a signed 0x00 (NULL, or 0) and an
unsigned 0x00? Can there be one? If I do the following:

char var;
var = 0x00;

what should var hold? and if it was an unsigned char, what should it
hold then? Thanks

Sona

Sona
Guest
Posts: n/a

 09-22-2003
Thanks for that Richard. That cleared it

My problem is that I need to send hex values to an embedded device to
get a response back. The manual says that sending '0x00' should return
0x88, but that's not working. I know this isn't related to C, but this

I send 0x99 to the device to switch it to "listening mode". This works..
I simple do:

char msg[2];

msg[0] = 0x99;
SendToDevice(uart, msg, 1);

where uart is a pointer to the device, msg is the char array that it
takes in and 1 is the number of characters to read from the array. This
works fine, that is, it activates the device.

This returns the correct result. I then send it two values, say:

msg[0] = 0x45;
msg[1] = 0x32;
SendToDevice(uart, msg, 2);

This works as well, I get the correct checksum in return. But then I
need to "initiliaze" the device by sending it 0x00 and it's supposed to
return 0x66 which isn't working.. I'm doing:

msg[0] = 0x00;
SendToDevice(uart, msg, 1);

And I get -91 in return. I posted another post about the itoa and atoi
problem just now defining that problem.. maybe it's something that I'm
doing wrong with my conversion but it seems to work fine for the first
two cases but fails with 0x00, or maybe the manual is wrong.. I don't
know. I'm new at this and am trying to learn but I can't seem to get
anywhere because apparantly my C isn't up to the mark Thanks for the
help! I hope you can shed some light on this?

Sona

Richard Bos wrote:

> Sona <(E-Mail Removed)> wrote:
>
>
>>What is the difference between a signed 0x00 (NULL, or 0) and an
>>unsigned 0x00? Can there be one?

>
>
> First, let's get rid of all the misconceptions.
>
> To begin with, 0x00 is always signed. It's a hexadecimal integral
> constant with the value 0, unsuffixed. This means that it is an int, and
> an int is signed.
> You probably meant "an object with all bits zero". Because of the
> previous point, 0x00 is not a good way to express this, but I'll assume
> you meant this anyway for the following points.
>
> The second point is that NULL is a null pointer constant, not a null
> pointer; the difference is important. A null pointer constant is a part
> of your source code, not an object. It can be 0, or (void*)0, or
> ('-'-'-'), or (void *)(1 - sizeof (char) ), or anything equivalent. It
> has no bit pattern as such; but in a pointer context, it is converted to
> a null pointer, which has.
> A null pointer, then, is not guaranteed to have the bit pattern "all
> zeroes". It often does; but this is not required. All that's required is
> that it is a distinct pointer that does not point at any valid object.
> Comparing a null pointer to 0 works because the 0, in this pointer
> context, is converted to another null pointer, not because the null
> pointer is in any way compared to an integral 0.
>
> Third, it doesn't matter. Signed integers must use the same
> representation for non-negative values as their unsigned counterparts;
> and this must be a pure binary representation. Moreover, all comparisons
> go by value, so if you compare 0x00 with 0x00u, they must compare equal.
>
>
>>If I do the following:
>>
>>char var;
>>var = 0x00;
>>
>>what should var hold?

>
>
> The value 0. An int with the value 0 is assigned to a char, and since
> that char can hold this value, the result should be as expected.
>
> Note that, since we don't know whether chars are signed or unsigned on
> your system, we don't know whether it's a signed or unsigned zero,
> either. Note also that, as above, it shouldn't matter a jot.
>
>
>>and if it was an unsigned char, what should it hold then?

>
>
> The value 0, in an unsigned char object.
>
> Richard

Dan Pop
Guest
Posts: n/a

 09-22-2003
In <3f6eea80\$(E-Mail Removed)> Sona <(E-Mail Removed)> writes:

>What is the difference between a signed 0x00 (NULL, or 0) and an

NULL doesn't belong to this context. It may defined as (void *)0, which
is quite a different beast than 0x0 and 0.

>unsigned 0x00? Can there be one? If I do the following:
>
>char var;
>var = 0x00;
>
>what should var hold? and if it was an unsigned char, what should it
>hold then? Thanks

In your example it doesn't matter what flavour of the 0 constant you're
using. There are contexts where it does matter, for example ~0u has a
well defined value, while ~0 is implementation-defined and can be even
a trap representation. But when used as an initialiser, the type of an
integer constant with the value 0 does not matter.

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: http://www.velocityreviews.com/forums/(E-Mail Removed)

Micah Cowan
Guest
Posts: n/a

 09-22-2003
Sona <(E-Mail Removed)> writes:

> Hi,
>
> What is the difference between a signed 0x00 (NULL, or 0) and an
> unsigned 0x00? Can there be one? If I do the following:

NULL is not necessarily the same thing as 0x00. It may be a pointer
type, and (if so) may not be represented as all-bits-zero.

>
> char var;
> var = 0x00;
>
> what should var hold? and if it was an unsigned char, what should it
> hold then? Thanks

Always positive zero. Negative zero can only occur on implementations which
use ones complement or sign-and-magnitude notation to represent
negative numbers. Both of these representations are extremely rare--I
have not personally encountered one. two's complement notation is
simpler to handle (requires no "special" handling of negative
numbers).

Even if you have such a representation on your C implementation,
negative zero may only result from:

1) Bit manipulation
2) Arithmetic where one operand is negative zero and the result is zero.

And, simply obtaining a negative zero can be a trap representation,
resulting in undefined behavior.

All of this doesn't mean you can assume your code won't encounter a
negative 0, but this is only a problem when you are making assumptions
about the representation of a particular "zero", and didn't roll your
own (i.e., 0x00 or the like). The cases where you actually have to
specifically account for negative zero are pretty rare. I've never had
to: generally, being responsible with your bitwise operations means not
producing such a thing in the first place (especially since you should be using
unsigned integers with your bitwise operators). Any code that *could*
produce a negative zero is not portable, since (as pointed out
earlier), negative zero may be a trap representation.

HTH,
-Micah

Micah Cowan
Guest
Posts: n/a

 09-22-2003
Sona <(E-Mail Removed)> writes:

> msg[0] = 0x00;
> SendToDevice(uart, msg, 1);
>
> And I get -91 in return. I posted another post about the itoa and atoi
> problem just now defining that problem.. maybe it's something that I'm
> doing wrong with my conversion but it seems to work fine for the first
> two cases but fails with 0x00, or maybe the manual is wrong.. I don't
> know. I'm new at this and am trying to learn but I can't seem to get
> anywhere because apparantly my C isn't up to the mark Thanks for
> the help! I hope you can shed some light on this?

This definitely has nothing to do with negative zeros. I'm afraid
that, as far as we can tell from what you have described, you are
sending correct data. Perhaps -91 is an error value?

-Micah

Keith Thompson
Guest
Posts: n/a

 09-22-2003
Sona <(E-Mail Removed)> writes:
> Thanks for that Richard. That cleared it
>
> My problem is that I need to send hex values to an embedded device to
> get a response back. The manual says that sending '0x00' should return
> 0x88, but that's not working. I know this isn't related to C, but this

[...]

You're not really sending hex values to your embedded device. You're
sending integer values (I'm guessing 8-bit unsigned integer values) to
the device; these values happen to be represented in hex in your C
program. (Unless the device is really expecting a sequence of ASCII
(or other character encoding) characters '0', 'x', '0', '0', but that
seems unlikely.) When you're programming on this level, it's
particularly important to understand the relationship between how
things are represented in your C source program (as character
sequences) and how they're represented in the actual hardware (as
bits, bytes, and words).

[...]
> But then I need to "initiliaze" the device by sending it 0x00 and
> it's supposed to return 0x66 which isn't working.. I'm doing:
>
> msg[0] = 0x00;
> SendToDevice(uart, msg, 1);
>
> And I get -91 in return. I posted another post about the itoa and atoi
> problem just now defining that problem.. maybe it's something that I'm
> doing wrong with my conversion but it seems to work fine for the first
> two cases but fails with 0x00, or maybe the manual is wrong.. I don't
> know. I'm new at this and am trying to learn but I can't seem to get
> anywhere because apparantly my C isn't up to the mark Thanks for
> the help! I hope you can shed some light on this?

How is SendToDevice declared? What type does it return? Your sample
code throws away the return value; how do you know it returns -91?

Assuming an 8-bit two's-complement result, -91, treated as an unsigned
8-bit value, is 0xa5. Does that make more sense?

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://www.sdsc.edu/~kst>
Schroedinger does Shakespeare: "To be *and* not to be"