Integral numeric types (C# reference)

The integral numeric types are a subset of the simple types and can be initialized with literals. All integral types are also value types.

All integral numeric types support arithmetic, bitwise logical, comparison, and equality operators.

Sizes and ranges

The following table shows the sizes and ranges of the integral types:

Type Range Size
sbyte -128 to 127 Signed 8-bit integer
byte 0 to 255 Unsigned 8-bit integer
short -32,768 to 32,767 Signed 16-bit integer
ushort 0 to 65,535 Unsigned 16-bit integer
int -2,147,483,648 to 2,147,483,647 Signed 32-bit integer
uint 0 to 4,294,967,295 Unsigned 32-bit integer
long -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 Signed 64-bit integer
ulong 0 to 18,446,744,073,709,551,615 Unsigned 64-bit integer

The default value for all integral types is 0. Each of the integral types has constants named MinValue and MaxValue for the minimum and maximum value for that type.

Use the System.Numerics.BigInteger structure to represent a signed integer with no upper or lower bounds.

Integral literals

Integral literals can be specified as decimal literals, hexadecimal literals, or binary literals. An example of each is shown below:

var decimalLiteral = 42;
var hexLiteral = 0x2A;
var binaryLiteral = 0b_0010_1010;

Decimal literals don't require any prefix. The x or X prefix signifies a hexadecimal literal. The b or B prefix signifies a binary literal. The declaration of binaryLiteral demonstrates the use of _ as a digit separator. The digit separator can be used with all numeric literals. Binary literals and the digit separator _ are supported starting with C# 7.0.

Literal suffixes

The l or L suffix specifies that the integral literal should be of the long type. The ul or UL suffix specifies the ulong type. If the L suffix is used on a literal that is greater than 9,223,372,036,854,775,807 (the maximum value of long), the value is converted to the ulong type. If the value represented by an integral literal exceeds UInt64.MaxValue, a compiler error CS1021 occurs.

Note

You can use the lowercase letter "l" as a suffix. However, this generates a compiler warning because the letter "l" is easily confused with the digit "1." Use "L" for clarity.

Type of an integral literal

If an integral literal has no suffix, its type is the first of the following types in which its value can be represented:

  1. int
  2. uint
  3. long
  4. ulong

You can convert an integral literal to a type with a smaller range than the default using either an assignment or a cast:

byte byteVariable = 42; // type is byte
var signedByte = (sbyte)42; // type is sbyte.

You can convert an integral literal to a type with a larger range than the default using either assignment, a cast, or a suffix on the literal:

var unsignedLong = 42UL;
var longVariable = 42L;
ulong anotherUnsignedLong = 42;
var anotherLong = (long)42;

Conversions

There's an implicit conversion (called a widening conversion) between any two integral types where the destination type can store all values of the source type. For example, there's an implicit conversion from int to long because the range of int values is a proper subset of long. There are implicit conversions from a smaller unsigned integral type to a larger signed integral type. There's also an implicit conversion from any integral type to any floating-point type. There's no implicit conversion from any signed integral type to any unsigned integral type.

You must use an explicit cast to convert one integral type to another integral type when an implicit conversion is not defined from the source type to the destination type. This is called a narrowing conversion. The explicit case is required because the conversion can result in data loss.

See also