432,002 Members | 2,157 Online
Need help? Post your question and get tips & solutions from a community of 432,002 IT Pros & Developers. It's quick & easy.

# unsigned and signed 0

 P: n/a 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 Nov 13 '05 #1
6 Replies

 P: n/a Sona 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 Nov 13 '05 #2

 P: n/a 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 might help you understand what my problem is: 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 wrote:What is the difference between a signed 0x00 (NULL, or 0) and anunsigned 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 Nov 13 '05 #3

 P: n/a In <3f********@clarion.carno.net.au> Sona 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 ithold 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: Da*****@ifh.de Nov 13 '05 #4

 P: n/a Sona 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 Nov 13 '05 #5

 P: n/a Sona 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 Nov 13 '05 #6

 P: n/a Sona 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 might help you understand what my problem is: [...] 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) ks*@cts.com San Diego Supercomputer Center <*> Schroedinger does Shakespeare: "To be *and* not to be" Nov 13 '05 #7

### This discussion thread is closed

Replies have been disabled for this discussion.