Integral numeric types (C# reference)
The integral numeric types represent integer numbers. All integral numeric types are value types. They are also simple types and can be initialized with literals. All integral numeric types support arithmetic, bitwise logical, comparison, and equality operators.
Characteristics of the integral types
C# supports the following predefined integral types:
| C# type/keyword | Range | Size | .NET type |
|---|---|---|---|
sbyte |
-128 to 127 | Signed 8-bit integer | System.SByte |
byte |
0 to 255 | Unsigned 8-bit integer | System.Byte |
short |
-32,768 to 32,767 | Signed 16-bit integer | System.Int16 |
ushort |
0 to 65,535 | Unsigned 16-bit integer | System.UInt16 |
int |
-2,147,483,648 to 2,147,483,647 | Signed 32-bit integer | System.Int32 |
uint |
0 to 4,294,967,295 | Unsigned 32-bit integer | System.UInt32 |
long |
-9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 | Signed 64-bit integer | System.Int64 |
ulong |
0 to 18,446,744,073,709,551,615 | Unsigned 64-bit integer | System.UInt64 |
nint |
Depends on platform | Signed 32-bit or 64-bit integer | System.IntPtr |
nuint |
Depends on platform | Unsigned 32-bit or 64-bit integer | System.UIntPtr |
In all of the table rows except the last two, each C# type keyword from the leftmost column is an alias for the corresponding .NET type. The keyword and .NET type name are interchangeable. For example, the following declarations declare variables of the same type:
int a = 123;
System.Int32 b = 123;
The nint and nuint types in the last two rows of the table are native-sized integers. They are represented internally by the indicated .NET types, but in each case the keyword and the .NET type are not interchangeable. The compiler provides operations and conversions for nint and nuint as integer types that it doesn't provide for the pointer types System.IntPtr and System.UIntPtr. For more information, see nint and nuint types.
The default value of each integral type is zero, 0. Each of the integral types except the native-sized types has MinValue and MaxValue constants that provide the minimum and maximum value of that type.
Use the System.Numerics.BigInteger structure to represent a signed integer with no upper or lower bounds.
Integer literals
Integer literals can be
- decimal: without any prefix
- hexadecimal: with the
0xor0Xprefix - binary: with the
0bor0Bprefix (available in C# 7.0 and later)
The following code demonstrates an example of each:
var decimalLiteral = 42;
var hexLiteral = 0x2A;
var binaryLiteral = 0b_0010_1010;
The preceding example also shows the use of _ as a digit separator, which is supported starting with C# 7.0. You can use the digit separator with all kinds of numeric literals.
The type of an integer literal is determined by its suffix as follows:
If the literal has no suffix, its type is the first of the following types in which its value can be represented:
int,uint,long,ulong.Note
Literals are interpreted as positive values. For example, the literal
0xFF_FF_FF_FFrepresents the number4294967295of theuinttype, though it has the same bit representation as the number-1of theinttype. If you need a value of a certain type, cast a literal to that type. Use theuncheckedoperator, if a literal value cannot be represented in the target type. For example,unchecked((int)0xFF_FF_FF_FF)produces-1.If the literal is suffixed by
Uoru, its type is the first of the following types in which its value can be represented:uint,ulong.If the literal is suffixed by
Lorl, its type is the first of the following types in which its value can be represented:long,ulong.Note
You can use the lowercase letter
las a suffix. However, this generates a compiler warning because the letterlcan be confused with the digit1. UseLfor clarity.If the literal is suffixed by
UL,Ul,uL,ul,LU,Lu,lU, orlu, its type isulong.
If the value represented by an integer literal exceeds UInt64.MaxValue, a compiler error CS1021 occurs.
If the determined type of an integer literal is int and the value represented by the literal is within the range of the destination type, the value can be implicitly converted to sbyte, byte, short, ushort, uint, ulong, nint or nuint:
byte a = 17;
byte b = 300; // CS0031: Constant value '300' cannot be converted to a 'byte'
As the preceding example shows, if the literal's value is not within the range of the destination type, a compiler error CS0031 occurs.
You can also use a cast to convert the value represented by an integer literal to the type other than the determined type of the literal:
var signedByte = (sbyte)42;
var longVariable = (long)42;
Conversions
You can convert any integral numeric type to any other integral numeric type. If the destination type can store all values of the source type, the conversion is implicit. Otherwise, you need to use a cast expression to perform an explicit conversion. For more information, see Built-in numeric conversions.
C# language specification
For more information, see the following sections of the C# language specification: