# long (C# Reference)

long denotes an integral type that stores values according to the size and range shown in the following table.

Type Range Size .NET type
long -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 Signed 64-bit integer System.Int64

## Literals

You can declare and initialize a long variable by assigning a decimal literal, a hexadecimal literal, or (starting with C# 7.0) a binary literal to it.

In the following example, integers equal to 4,294,967,296 that are represented as decimal, hexadecimal, and binary literals are assigned to long values.

long longValue1 = 4294967296;
Console.WriteLine(longValue1);

long longValue2 = 0x100000000;
Console.WriteLine(longValue2);

long longValue3 = 0b1_0000_0000_0000_0000_0000_0000_0000_0000;
Console.WriteLine(longValue3);
// The example displays the following output:
//          4294967296
//          4294967296
//          4294967296


Note

You use the prefix 0x or 0X to denote a hexadecimal literal and the prefix 0b or 0B to denote a binary literal. Decimal literals have no prefix.

Starting with C# 7.0, a couple of features have been added to enhance readability.

• C# 7.0 allows the usage of the underscore character, _, as a digit separator.
• C# 7.2 allows _ to be used as a digit separator for a binary or hexadecimal literal, after the prefix. A decimal literal isn't permitted to have a leading underscore.

Some examples are shown below.

long longValue1 = 4_294_967_296;
Console.WriteLine(longValue1);

long longValue2 = 0x1_0000_0000;
Console.WriteLine(longValue2);

long longValue3 = 0b1_0000_0000_0000_0000_0000_0000_0000_0000;
Console.WriteLine(longValue3);

long longValue4 = 0x_1_0000_0000;       // C# 7.2 onwards
Console.WriteLine(longValue4);

long longValue5 = 0b_1_0000_0000_0000_0000_0000_0000_0000_0000;       // C# 7.2 onwards
Console.WriteLine(longValue5);
// The example displays the following output:
//          4294967296
//          4294967296
//          4294967296
//          4294967296
//          4294967296


Integer literals can also include a suffix that denotes the type. The suffix L denotes a long. The following example uses the L suffix to denote a long integer:

long value = 4294967296L;


Note

You can also 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.

When you use the suffix L, the type of the literal integer is determined to be either long or ulong, depending on its size. In this case, it is long because it less than the range of ulong.

A common use of the suffix is to call overloaded methods. For example, the following overloaded methods have parameters of type long and int:

public static void SampleMethod(int i) {}
public static void SampleMethod(long l) {}


The L suffix guarantees that the correct overload is called:

SampleMethod(5);    // Calls the method with the int parameter
SampleMethod(5L);   // Calls the method with the long parameter


If an integer 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

The literal 4294967296 in the previous examples is of type long, because it exceeds the range of uint (see Integral Types Table for the storage sizes of integral types).

If you use the long type with other integral types in the same expression, the expression is evaluated as long (or bool in the case of relational or Boolean expressions). For example, the following expression evaluates as long:

898L + 88


For information on arithmetic expressions with mixed floating-point types and integral types, see float and double.

## Conversions

There is a predefined implicit conversion from long to float, double, or decimal. Otherwise a cast must be used. For example, the following statement will produce a compilation error without an explicit cast:

int x = 8L;        // Error: no implicit conversion from long to int
int y = (int)8L;   // OK: explicit conversion to int


There is a predefined implicit conversion from sbyte, byte, short, ushort, int, uint, or char to long.

Notice also that there is no implicit conversion from floating-point types to long. For example, the following statement generates a compiler error unless an explicit cast is used:

long x = 3.0;         // Error: no implicit conversion from double
long y = (long)3.0;   // OK: explicit conversion


## C# Language Specification

For more information, see Integral types in the C# Language Specification. The language specification is the definitive source for C# syntax and usage.