The sbyte type  
Author Message
Karim Hemani





PostPosted: Visual C# Language, The sbyte type Top

Hi,

In Learning C# by Jesse Liberty, the author states that the sbyte type can store numbers from -128 to 127. I was wondering whether or not the last bit (8th) is used to store the number's sign. If it does, then how can the remaining 7 bits store a number as large as 128. The largest number that 7 bits can store is 127. So shouldn't the range for the sbyte type be -127 to 127 instead of -128 to 127 as the author has specified. Please clarify this confusion.

Thanks,

Karim Hemani



Visual C#19  
 
 
cgraus





PostPosted: Visual C# Language, The sbyte type Top

Yes, the top bit is always used to store the sign. However, bear in mind that this means you have two values for 0, one with the sign set and one without. So, I would guess that is where your extra value comes from.



 
 
IanG





PostPosted: Visual C# Language, The sbyte type Top

It uses a binary representation called two's complement. This system is pretty much ubiquitous - almost any computer you're likely to come across, whether it's a PC, mainframe, or a cellphone, is likely to use this system.

You can indeed tell the sign by looking at the top bit, but it's not as simple as saying that '00000010' is 2 and '10000010' is minus 2 - that's not how it works. Instead, negative numbers are created by inverting all the bits and then adding 1.

So let's take 2. Positive 2 is '00000010'. Flip the bits - you get '11111101'. Finally add 1. You get '11111110'.

Why do this Two reasons. First, it means you don't waste a bit pattern by having two different zeros. (You don't need both a negative zero and a positive zero.) Secondly, and more importantly, it means you can use exactly the same hardware to perform signed arithmetic and unsigned arithmetic. Let's look at what happens if you add 4 to '11111110':

  11111110

+00000100

 --------

100000010

Notice that the result doesn't fit into 8 bits. Truncating into 8 we get '00000010'. So in other words, by adding 4, we ended up with 2. That's what we'd expect given that we started with -2!

So that's the major appeal of 2's complement. Using hardware designed to add unsigned numbers together, and then truncating the results turns out to produce the correct results for signed numbers too!

So, why -128 rather than -127 Well the short answer is because we add 1 after flipping the bits, so negative numbers end up getting one extra number.

The alternative way of looking at it though is that 0 throws a spanner in the works. You can represent 128 numbers with the top bit set and another 128 numbers with the top bit cleared. Zero has to come somewhere, and we represent that as all zero digits, obviously enough. This means that zero gets to 'steal' one of the values with the top bit clear. There are 128 non-negative numbers: 0 through 127.

It would be a waste to have a separate representation for negative zero. (Actually, floating point does support that, but FP is different.) So we get to use all 128 top-bit-set bit patterns for negative numbers. Since we don't 'waste' one pattern for 0, this means we can go from -1 to -128.

Hope that helps.


 
 
Karim Hemani





PostPosted: Visual C# Language, The sbyte type Top

Thanks a lot, IanG. Your answer clarified all the confusion.