79

I don't understand why the lowest value a byte can take is -128. I can see that the highest value is 127, because it's 01111111 in binary, but how does one represent -128 with only 8 bits, one of which is used for the sign? Positive 128 would already be 8-bit, i.e. 10000000, and then you would need a 9th bit to represent the negative sign.

Could someone please help explain this to me.

wattostudios
  • 8,446
  • 13
  • 40
  • 54
Bad Request
  • 3,810
  • 5
  • 29
  • 35
  • 22
    [Two's Complement](http://en.wikipedia.org/wiki/Two's_complement) – James McNellis Sep 01 '10 at 18:34
  • 1
    It's similar for the other integer types `short`, `int` and `long`. – starblue Sep 01 '10 at 19:19
  • 11
    A better question is `why java byte type is not a range of 0..255`? In fact many do ask this question, in most languages `byte` type is unsigned, but in java `byte` is signed too, and I (and many other) believe that it was a bad design which remained in Java from day one. There are issues when you are working JNI, and believe me when you name something `byte` you want 0..255! – Amir Pashazadeh Jan 11 '14 at 05:02

8 Answers8

94

The answer is two's complement.

In short, Java (and most modern languages) do not represent signed integers using signed-magnitude representation. In other words, an 8-bit integer is not a sign bit followed by a 7-bit unsigned integer.

Instead, negative integers are represented in a system called two's complement, which allows easier arithmetic processing in hardware, and also eliminates the potential ambiguity of having positive zero and negative zero. A side effect of eliminating negative zero is that there is always one extra negative number available at the bottom of the range.

Another interesting property of two's complement systems is that the first bit does effectively function as a sign indicator (i.e. all numbers beginning with the bit 1 are negative), but the next seven bits are not to be interpreted on their own as an unsigned number to which the sign bit is applied.

Two's complement isn't terribly complicated, but getting an initial good grip on what two's complement is and how and why it works is probably beyond the scope of an SO answer. Start with the Wikipedia article, or google the term for more resources.

To try to briefly address your query about -128, the fundamental idea behind generating a two's complement number is to take the unsigned form of the number, invert all of the bits and add one. So unsigned 128 is 10000000. Inverted, it's 01111111, and adding one gets 10000000 again. So in a two's complement system, 10000000 is unambiguously -128 and not +128. Numbers greater than or equal to +128 simply cannot be represented in 8 bits using a two's complement system because they would be ambiguous with the forms of negative numbers.

Tyler McHenry
  • 68,965
  • 15
  • 114
  • 158
  • Neat! Let's see if I got it right though: it is still true that 8-bit numbers that start with 0 (other than 00000000) ARE positive, and starting with 1 ARE negative? Also, the only really tricky thing about two's complement is that the bit representation of bytes don't have the same value that they do in a math class, i.e. 10000000 is normally +128, but as a byte it's -128. Amirite? – Bad Request Sep 01 '10 at 18:58
  • You're correct. The first bit is 1 if and only if the number is negative. If the first bit is 0, the number is either positive or zero. – Tyler McHenry Sep 01 '10 at 19:04
  • @Tyler: I bet you could answer my question under this post as well: http://stackoverflow.com/questions/16775169/java-binary-literals-value-128-for-byte I hope this is not too straight foreward but i realy wonder and after a few months of sporadicially searching i still dont have a clue:~ – JBA Sep 09 '13 at 12:16
  • Whi this code byte b1 = 0b10000000; makes compile error? – zeds Dec 04 '15 at 17:27
34

Two´s complement works as follows;

A byte consists of 8 bits.

00000000 means 0

11111111 means 255

However, if the numbers were presented like that, we would not differentiate between whether the resulting number is positive or negative. Because of this reason, the bit on the left side gives us this information. If the bit on the left side is 0, you can start adding the value of other bits on the top of zero. If the bit is 1, you should start adding on the top of -128. Because the bit on the left side is two to the power of seven.

Examples;

In these examples, the bit on the left side is 1, it means we are adding the values of other bits on the top of -128.

10000000 = -128 (-128 + 0)

10000001 = -127 (-128 + 1)

10000011 = -125 (-128 + 3)

10000111 = -121 (-128 + 7)

Same bits but this time, the bit on the left is 0. That means we are starting to add on the top of 0.

00000000 = 0 (0 + 0)

00000001 = 1 (0 + 1)

00000011 = 3 (0 + 3)

00000111 = 7 (0 + 7)

If we are ok until now, the answer to your question,

the smallest possible number

10000000 = -128

the biggest possible number

011111111 = 127

That is why the range is between -128 and 127.

Ad Infinitum
  • 3,033
  • 19
  • 30
8

As James pointed out in his comment, it's because that's how two's complement works.

If we put it in other terms, you can represent 2^8 = 256 kind of values. which is, in this case used as 128 negative numbers, 127 positive numbers, and zero. If we used 7 bits to represent the value, +1 bit for a sign, we could represent one less value and would also have two zeros (which would be very unfortunate as comparing two values would be more complicated because of that).

Tamás Szelei
  • 21,352
  • 16
  • 94
  • 169
3

Basic numeric types can represent 2^n numbers. Look at a case n=2. You can represent four cases, lets call them a, b, c, d. Then you can agree to either a=-2, b=-1, c=0, d=1 (this is accepted way) or a=-1, b=0, c=1, d=2 (Possible, but not used). So, if you only have one zero and hold 2^n states your abs(min) != max Increasing the n moves the borders, but abs(min) != max still holds.

Sic
  • 31
  • 3
3

byte consist of 8 bit ---> 1 bit sign (positive or negative ) 7 bit value

so the range -2^7 negative (-128 ) to 2^7 -1 positive(127)

Mina Fawzy
  • 18,268
  • 13
  • 118
  • 129
1

in java all the variables like byte short int long float double are written as signed . so is very simple the head bit always specifies what is( negative or positive), but because the numbers are dividable by 2 half is shifted as negative , 0 is positive by default . so it looks like this :

this is positive
+|0001001
1|0001001
this is negative
-|0001001
0|0001001
as a byte short a negative is
-000000011111111
0000000011111111

0

Without getting into two's complement: 2^8 (since a byte is 8 digits and can have 1 of 2 values) = 256, so the most individual values a byte can represent is 256. so, representing the numbers -128 to -1 is half our range. I believe the question here is why is the max positive value 127 rather than 128. This is because we have to represent the number 0, so inclusively 0-127 is the other 128 possibilities of our range.

If we were only allowing positive values, such as an unsigned byte where negative numbers aren't possible, the range would be 0-255, since these are 256 different values (including the 0).

David Hollowell - MSFT
  • 1,043
  • 2
  • 9
  • 18
0

after taking two's compliment of number we always left with one state of representing number extra so we turn that state to -128.

Rashid Ali
  • 11
  • 3