Question
In C, I understand that an int on some systems may be 32 bits, but I have seen a range of -32,768 to 32,767. In Java, I have seen that integers range from -2,147,483,648 to 2,147,483,647.
How can the ranges differ when the number of bits appears to be the same? Also, is Java long a 32-bit type?
Short Answer
Integer ranges depend on both the number of bits and whether the type is signed or unsigned. The apparent discrepancy comes from mixing up 16-bit and 32-bit ranges: -32,768 to 32,767 is the usual range of a 16-bit signed integer, while -2,147,483,648 to 2,147,483,647 is the range of a 32-bit signed integer. In Java, int is 32 bits and long is 64 bits. In C, the size of int is implementation-defined, although it is commonly 32 bits today.
Concept
A computer stores an integer as a fixed number of binary digits, called bits. Each bit can be 0 or 1.
For an unsigned integer with n bits, every bit represents magnitude, so there are 2^n possible values:
0 through 2^n - 1
For a signed integer, one bit is effectively used to distinguish negative values from non-negative values. On modern systems using two's-complement representation, its range is:
-2^(n - 1) through 2^(n - 1) - 1
Therefore:
| Type width | Signed range | Unsigned range |
|---|---|---|
| 16 bits | -32,768 to 32,767 | 0 to 65,535 |
| 32 bits | to |
Mental Model
Think of bits as switches in a row.
- A 16-switch row has
2^16, or 65,536, possible switch patterns. - A 32-switch row has
2^32, or 4,294,967,296, possible patterns.
A signed number needs to represent both debts and balances: negative and positive values. It splits the available patterns between them.
A 16-bit signed integer has about half its patterns for negatives and half for non-negative numbers, giving a maximum of 32,767.
A 32-bit signed integer has vastly more patterns, giving a maximum of 2,147,483,647.
So the important question is not only “is it an integer?” but also “how many bits does this particular integer type have?”
Syntax and Examples
In Java, primitive integer sizes are fixed:
int score = 2_147_483_647; // Largest int value
long population = 2_147_483_648L; // Needs long; L marks a long literal
System.out.println(Integer.MAX_VALUE);
System.out.println(Long.MAX_VALUE);
Integer.MAX_VALUE prints:
2147483647
Long.MAX_VALUE prints:
9223372036854775807
In C, use <limits.h> rather than assuming a width:
#include <stdio.h>
#include <limits.h>
int main(void) {
printf("int range: %d to %d\n", INT_MIN, INT_MAX);
printf("int bits: %zu\n", sizeof() * CHAR_BIT);
;
}
Step by Step Execution
Consider this Java expression:
int max = Integer.MAX_VALUE;
System.out.println(max);
System.out.println(max + 1);
Step by step:
Integer.MAX_VALUEis2,147,483,647, the largest value that fits in a Javaint.- The first
printlndisplays that maximum value. max + 1tries to create2,147,483,648.- That value cannot fit in a 32-bit signed
int. - Java integer arithmetic wraps around, so the result becomes
-2,147,483,648, which isInteger.MIN_VALUE.
Output:
2147483647
-2147483648
Use long before performing the calculation when the result may exceed the int range:
long next () max + ;
System.out.println(next);
Real World Use Cases
Integer widths matter whenever a program stores counts, identifiers, sizes, money units, or binary data.
- File sizes: A file can be larger than the maximum 32-bit signed value, so file APIs often use 64-bit values.
- Database IDs: An application may begin with
intIDs but needlongIDs as records grow. - Timestamps: Java timestamps and durations commonly use
longbecause seconds or milliseconds can exceedintlimits. - Network protocols: A protocol may specify an unsigned 16-bit or 32-bit field. The exact width is part of the protocol contract.
- Image processing: Pixel channels often use 8-bit unsigned values; image dimensions or total pixel counts may require larger integer types.
- Embedded C programs: Hardware registers may be exactly 8, 16, or 32 bits, making
uint16_tanduint32_tuseful.
Real Codebase Usage
In real code, developers avoid guessing numeric limits and make width choices intentional.
Use named limits
Java exposes limits through wrapper classes:
if (requestedCount > Integer.MAX_VALUE) {
throw new IllegalArgumentException("Count is too large");
}
C exposes limits through standard headers:
#include <limits.h>
if (count > INT_MAX) {
/* handle value that cannot fit in int */
}
Use long for calculations that can grow
Even if each input is an int, their product may not fit in one:
int width = 50_000;
int height = 50_000;
long pixels = (long) width * height;
Casting before multiplication is important. Otherwise, Java performs the multiplication as int first.
Common Mistakes
Assuming a 32-bit machine means every C integer is 32 bits
A machine's “bitness” usually refers to its main architecture or pointer size. It does not define every C type.
/* Do not assume this is always 32 bits. */
int value;
Avoid the assumption by checking sizeof(int) * CHAR_BIT or using int32_t when an exact 32-bit type is required.
Mixing up Java int and long
Java int is 32 bits. Java long is 64 bits.
int small = 100;
long large = 100L;
Writing a too-large Java integer literal without L
This does not compile because the literal is interpreted as an int first:
long value ;
Comparisons
| Feature | Java int | Java long | Typical C int | C int32_t |
|---|---|---|---|---|
| Width | Always 32 bits | Always 64 bits | Implementation-defined, often 32 bits | Exactly 32 bits when available |
| Signed? | Yes | Yes | Yes | Yes |
| Typical range | -2^31 to 2^31 - 1 | -2^63 to 2^63 - 1 | Depends on system | to |
Cheat Sheet
-32,768to32,767is the usual 16-bit signed range.-2,147,483,648to2,147,483,647is the 32-bit signed range.- Signed
n-bit range:-2^(n-1)to2^(n-1) - 1. - Unsigned
n-bit range:0to2^n - 1. - Java
intis always 32 bits. - Java
longis always 64 bits. - C
intis at least 16 bits and is commonly 32 bits, but its exact width is platform-dependent. - In C, include
<limits.h>and useINT_MIN/INT_MAXforintlimits. - In C, use
<stdint.h>types such asint32_twhen a precise width is needed. - In Java, use
Integer.MAX_VALUE, , , and .
FAQ
Is a C int always 32 bits?
No. C guarantees only a minimum range for int. It is commonly 32 bits on modern systems, but portable code should not assume that without checking.
Is Java long 32 bits?
No. Java long is always a signed 64-bit integer. Java int is the signed 32-bit integer type.
Why is the positive maximum one smaller than the negative magnitude?
With two's-complement signed representation, one bit pattern represents zero and there is one extra negative value. Therefore, a 32-bit signed type goes from -2^31 through 2^31 - 1.
What is the range of a 32-bit unsigned integer?
It ranges from 0 to 4,294,967,295 (2^32 - 1).
What happens when a Java int exceeds its maximum value?
Normal int arithmetic wraps around. Integer.MAX_VALUE + 1 becomes Integer.MIN_VALUE.
How can I find the size of a C integer type?
Mini Project
Description
Build a small Java range checker for values that may need to be stored as an int. This mirrors a common application boundary: receiving a large count or identifier and validating that it fits before narrowing it to a smaller type.
Goal
Read several long values, report whether each fits in a Java int, and safely convert valid values.
Requirements
Requirement 1
Keep learning
Related questions
2D Array Loop Order and Cache Performance in C
Learn why swapping nested loops changes 2D array performance in C, using row-major memory layout, cache locality, and practical benchmarks.
Array-to-Pointer Conversion in C and C++ Explained
Learn what array-to-pointer conversion means in C and C++, how array decay works, and how it differs from a pointer to an array.
Building More Fault-Tolerant Embedded C++ Applications for Radiation-Prone ARM Systems
Learn practical C++ and compile-time techniques to reduce soft-error damage in embedded ARM systems exposed to radiation.