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.
Answer from Tyler McHenry on Stack OverflowThe 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.
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.
Videos
1 byte = 8 bit... But where does the 128 & -127 range come from?
EDIT: Another type that I am confused about it's origin on is the integer type:
An integer is assumed to be of the int type, whose value is between -231 (-2147483648) and 231 - 1 (2147483647).
Where did that value come from?!? Also, does being a long type mean that it has a larger range than integers for values?
First of all, normally 8 bits means a value range from 0 to 255. However, I understand that a bit is used to denote positive/negative therefore the new expected range is now -127 to 127.
However, according to documentation, the actual range is -128 to 127. I don't understand how it's possible. Given 8 bits, this is how -127 is represented:
Neg? 64 32 16 8 4 2 1 1 1 1 1 1 1 1 1
Where does the extra +1 come from?