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 Overflow
Top answer
1 of 8
103

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.

2 of 8
42

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.

🌐
Quora
quora.com › What-is-the-range-of-data-type-byte-in-Java
What is the range of data type byte in Java? - Quora
This means it can represent values in the range from -128 to 127. Here's the specific range: * Minimum value: -128 * Maximum value: 127 For example, you can declare a [code ]byte[/code...
🌐
IBM
ibm.com › docs › en › i › 7.4.0
COBOL and Java Data Types
We cannot provide a description for this page right now
🌐
Oracle
docs.oracle.com › javase › tutorial › java › nutsandbolts › datatypes.html
Primitive Data Types (The Java™ Tutorials > Learning the Java Language > Language Basics)
It has a minimum value of -128 and a maximum value of 127 (inclusive). The byte data type can be useful for saving memory in large arrays, where the memory savings actually matters. They can also be used in place of int where their limits help to clarify your code; the fact that a variable's ...
🌐
CodeGym
codegym.cc › java blog › java types › java byte keyword
Java Byte Keyword
September 28, 2023 - Hence the numeric range of a byte spans from -2^7 = -128 upto +2^7-1 =127. Have a look at the following illustration to have a better understanding of how we can compute this range.
🌐
DataCamp
datacamp.com › doc › java › byte
byte Keyword in Java: Usage & Examples
Incrementing a by 1 causes an overflow, resulting in the value wrapping around to -128. Memory Efficiency: Use byte when you need to save memory, especially in large arrays. Range Checking: Always ensure that the values assigned to a byte variable are within the range of -128 to 127 to avoid ...
🌐
Quora
quora.com › Why-does-the-byte-data-type-in-Java-store-numbers-within-the-range-of-128-to-127
Why does the byte data type in Java store numbers within the range of -128 to+ 127? - Quora
Answer (1 of 5): Java byte is signed meaning the most significant bit is reserved for sign. Byte is composed of 8 bits but as MSB is reserved for signed so we have only 7 bits to represent the value (last 8th bit represents the sign 1 for negative ...
Find elsewhere
🌐
Coderanch
coderanch.com › t › 597865 › java › data-range-byte
data range in byte (Java in General forum at Coderanch)
... Hello every one We all know that byte Variables can have values from -128 to +127 and occupy 1 byte (8 bits) in memory so 0 1 1 1 1 1 1 1 => +127 as first digit is 0 which means +ive means max number represented by byte but what should be the least number..byte defination says it can be ...
🌐
LabEx
labex.io › tutorials › java-how-to-check-if-an-integer-is-within-byte-range-in-java-560006
How to Check If an Integer Is Within Byte Range in Java | LabEx
We will begin by understanding the defined range of a byte, which is from -128 to 127. Following this, you will learn how to compare an integer with these byte limits to determine if it is within the valid range.
🌐
Learneroo
learneroo.com › modules › 22 › nodes › 165
More on Data Types - Learneroo
The size in measured in bits, i.e. a single 1 or 0. The range of an integer data type is simply 2bits. For example, an 8-bit number will be able to hold 256 values. There are 4 integer data types in Java. byte and short are the 2 uncommon ones, which you may never need:
🌐
Sololearn
sololearn.com › en › Discuss › 231214 › how-is-byte-b-accepting-256-when-range-of-byte-is-128-to-128
How is byte b accepting +256 when range of byte is -128 to +128. | Sololearn: Learn to code for FREE!
Specialty of Java type cast - Java allows to store any 256 values as byte if you force it to. And you do by casting int 256 to byte. ... No. 257 will overflow and output 1. ... The range of a byte has 256 possibilities. The range is -128 to 127.
🌐
Medium
medium.com › @malindurnawarathne › what-happen-if-you-exceed-the-byte-range-in-java-128-to-127-561c5838356b
What happen if you exceed the Byte Range in Java? (128 to -127) | by Malindu Ransara Nawarathne | Medium
November 29, 2021 - What happen if you exceed the Byte Range in Java? (128 to -127) Hi, everyone…. You will probably think exceeding a numeric range in programming language like Java will prompt error like this …
🌐
How to do in Java
howtodoinjava.com › home › java basics › primitive data types
Java Primitive Datatypes and Ranges (with Examples)
May 24, 2023 - You must use a cast to make such an assignment from int to byte. ... The short data type is a 16-bit signed Java primitive integer data type. Its range is -32768 to 32767. Unlike int and long literals, there is no short literal.
🌐
Sarthaks eConnect
sarthaks.com › 2433624 › what-is-the-range-of-byte-data-type-in-java
What is the range of byte data type in Java? - Sarthaks eConnect | Largest Online Education Community
What is the range of byte data type in Java? (a) -128 to 127 (b) -32768 to 32767 (c) -2147483648 to 2147483647 (d) None of the mentioned
🌐
iO Flood
ioflood.com › blog › java-byte
Java Byte: A Memory-Efficient Primitive Data Type
February 26, 2024 - A byte takes up only 8 bits of memory, making it a memory-efficient choice when dealing with large amounts of data. However, one potential pitfall of using byte is its limited range of values (-128 to 127).
🌐
O'Reilly
oreilly.com › library › view › java-i-o › 1565924851 › ch01s02.html
Numeric Data - Java I/O [Book]
March 16, 1999 - In the case of 3000000000 or similar ... big-endian, two’s complement integers with ranges from -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807....
Author   Elliotte Rusty Harold
Published   1999
Pages   600
🌐
W3Schools
w3schools.com › java › java_data_types.asp
Java Data Types
assert abstract boolean break byte case catch char class continue default do double else enum exports extends final finally float for if implements import instanceof int interface long module native new package private protected public return requires short static super switch synchronized this throw throws transient try var void volatile while Java String Methods