An integer type is a value type that represents a whole number, without a fractional part. It can be positive, negative, or zero.
Integers are part of the primitive or basic data types in C# and are used to store numeric values that do not require decimal precision.
Integer types in C# are Value Types. This means they are stored directly on the Stack, making them very fast and efficient.
Types of integers in C#
C# offers us different sizes of integers. Furthermore, there are signed and unsigned versions.
- Signed integers can represent both positive and negative numbers.
- Unsigned integers can represent only positive numbers.
Here is the “complete family” of integer types in C#:
| C# Keyword | .NET Type (System) | Size | Signed? | Approximate Range |
|---|---|---|---|---|
sbyte | SByte | 8 bits | Yes | -128 to 127 |
byte | Byte | 8 bits | No | 0 to 255 |
short | Int16 | 16 bits | Yes | -32,768 to 32,767 |
ushort | UInt16 | 16 bits | No | 0 to 65,535 |
int | Int32 | 32 bits | Yes | -2 billion to 2 billion |
uint | UInt32 | 32 bits | No | 0 to 4 billion |
long | Int64 | 64 bits | Yes | Very large (±9 trillion) |
ulong | UInt64 | 64 bits | No | Absurdly large |
There are also nint and nuint (Native Integers), which depend on the processor architecture (32 or 64 bits), but that’s for advanced interop and pointer topics.
With so many options (short, int, long), which one do I choose?
- By default, use
int: Processors are optimized to work with 32-bit blocks. Even if you store a small number (e.g., 5) in alongor ashort, it’s sometimes slower than usingint. - Use
longif you think the number might exceed 2 billion (database IDs, global counters, timestamps). - Use
byteonly if you are working with binary data arrays (files, images, streams). - Avoid
unsignedtypes (uint,ulong) for general arithmetic. Subtractions can give strange results if the result should be negative and wraps around the maximum value.
Declaration and Initialization
To declare an integer we use the type keyword followed by the variable name.
int edad = 35;
long distanciaEstrellas = 9000000000000L;
Notice that L at the end of the long number. That is a literal suffix.
When we write a number “raw” in the code (like 35), C# assumes by default that it’s an int. If the number is too large for an int, we need to explicitly tell it “hey, this is a long” using the L suffix.
Arithmetic Operations
Integers in C# support a variety of mathematical operations, including addition, subtraction, multiplication, division, and modulus.
Examples of these operations are shown below:
int a = 10;
int b = 3;
int suma = a + b; // 13
int resta = a - b; // 7
int multiplicacion = a * b; // 30
int division = a / b; // 3 (integer division)
int modulo = a % b; // 1 (remainder of division)
Keep in mind that division between two integers in C# is integer division, meaning the result is truncated and the decimal part is not included. For example, 10 / 3 results in 3, not 3.333....
If you need decimals, at least one of the operands must be a floating-point type (float, double, or decimal).
Integer Limits
Each integer type in C# has a specific range of values. If we try to assign a value outside this range, a compilation error or unexpected runtime behavior will occur.
Overflow occurs when we try to store a value that exceeds the maximum allowed range for an integer type. For example:
int maxInt = int.MaxValue; // 2,147,483,647
int overflow = maxInt + 1; // This will cause an overflow
In this case, maxInt + 1 exceeds the maximum value an int can store, resulting in undefined behavior.
In C#, by default, arithmetic operations do not check for overflow for performance. The bits simply “wrap around”.
To handle overflow safely, we can use the checked keyword:
checked
{
int maxInt = int.MaxValue;
int overflow = maxInt + 1; // This will throw an OverflowException
}
Underflow occurs when we try to store a value that is less than the minimum allowed range for an integer type. For example:
int minInt = int.MinValue; // -2,147,483,648
int underflow = minInt - 1; // This will cause an underflow
Just like with overflow, underflow can be handled using the checked keyword.
If you are doing critical calculations (money, nuclear reactor control, etc.) and you want the program to warn if there is overflow, you can use a checked block.
Practical Examples
Sum of Two Integers
This example shows how to add two integers entered by the user:
Console.Write("Enter the first number: ");
int num1 = int.Parse(Console.ReadLine());
Console.Write("Enter the second number: ");
int num2 = int.Parse(Console.ReadLine());
int suma = num1 + num2;
Console.WriteLine($"The sum is: {suma}");
Range Verification
This example shows how to verify if a number is within the allowed range for an int:
int min = int.MinValue;
int max = int.MaxValue;
Console.Write("Enter a number: ");
int num = int.Parse(Console.ReadLine());
if (num >= min && num <= max)
{
Console.WriteLine("The number is within the allowed range.");
}
else
{
Console.WriteLine("The number is outside the allowed range.");
}
Using checked to Handle Overflows
This example shows how to use checked to detect overflows:
checked
{
int maxInt = int.MaxValue;
try
{
int overflow = maxInt + 1;
}
catch (OverflowException)
{
Console.WriteLine("An overflow occurred.");
}
}
