Numerics in .NET

.NET provides a range of numeric integer and floating-point primitives, as well as:

Integer types

.NET supports both signed and unsigned 8-bit, 16-bit, 32-bit, 64-bit, and 128-bit integer types, which are listed in the following tables.

Signed integer types

Type Size (in bytes) Minimum value Maximum value
System.Int16 2 -32,768 32,767
System.Int32 4 -2,147,483,648 2,147,483,647
System.Int64 8 -9,223,372,036,854,775,808 9,223,372,036,854,775,807
System.Int128 16 −170,141,183,460,469,231,731,687,303,715,884,105,728 170,141,183,460,469,231,731,687,303,715,884,105,727
System.SByte 1 -128 127
System.IntPtr (in 32-bit process) 4 -2,147,483,648 2,147,483,647
System.IntPtr (in 64-bit process) 8 -9,223,372,036,854,775,808 9,223,372,036,854,775,807

Unsigned integer types

Type Size (in bytes) Minimum value Maximum value
System.Byte 1 0 255
System.UInt16 2 0 65,535
System.UInt32 4 0 4,294,967,295
System.UInt64 8 0 18,446,744,073,709,551,615
System.UInt128 16 0 340,282,366,920,938,463,463,374,607,431,768,211,455
System.UIntPtr (in 32-bit process) 4 0 4,294,967,295
System.UIntPtr (in 64-bit process) 8 0 18,446,744,073,709,551,615

Each integer type supports a set of standard arithmetic operators. The System.Math class provides methods for a broader set of mathematical functions.

You can also work with the individual bits in an integer value by using the System.BitConverter class.

Note

The unsigned integer types are not CLS-compliant. For more information, see Language independence and language-independent components.

BigInteger

The System.Numerics.BigInteger structure is an immutable type that represents an arbitrarily large integer whose value in theory has no upper or lower bounds. The methods of the BigInteger type closely parallel those of the other integral types.

Floating-point types

.NET includes the following floating-point types:

Type Size (in bytes) Approximate range Primitive? Notes
System.Half 2 ±65504 No Introduced in .NET 5
System.Single 4 ±3.4 x 1038 Yes
System.Double 8 ±1.7 × 10308 Yes
System.Decimal 16 ±7.9228 x 1028 No

The Half, Single, and Double types support special values that represent not-a-number and infinity. For example, the Double type provides the following values: Double.NaN, Double.NegativeInfinity, and Double.PositiveInfinity. You use the Double.IsNaN, Double.IsInfinity, Double.IsPositiveInfinity, and Double.IsNegativeInfinity methods to test for these special values.

Each floating-point type supports a set of standard arithmetic operators. The System.Math class provides methods for a broader set of mathematical functions. .NET Core 2.0 and later includes the System.MathF class, which provides methods that accept arguments of the Single type.

You can also work with the individual bits in Double, Single, and Half values by using the System.BitConverter class. The System.Decimal structure has its own methods, Decimal.GetBits and Decimal(Int32[]), for working with a decimal value's individual bits, as well as its own set of methods for performing some additional mathematical operations.

The Double, Single, and Half types are intended to be used for values that, by their nature, are imprecise (for example, the distance between two stars) and for applications in which a high degree of precision and small rounding error is not required. Use the System.Decimal type for cases in which greater precision is required and rounding errors should be minimized.

Note

The Decimal type doesn't eliminate the need for rounding. Rather, it minimizes errors due to rounding.

Complex

The System.Numerics.Complex structure represents a complex number, that is, a number with a real number part and an imaginary number part. It supports a standard set of arithmetic, comparison, equality, explicit and implicit conversion operators, as well as mathematical, algebraic, and trigonometric methods.

SIMD-enabled types

The System.Numerics namespace includes a set of .NET SIMD-enabled types. SIMD (Single Instruction Multiple Data) operations can be parallelized at the hardware level. That increases the throughput of the vectorized computations, which are common in mathematical, scientific, and graphics apps.

The .NET SIMD-enabled types include the following:

  • The Vector2, Vector3, and Vector4 types, which represent vectors with 2, 3, and 4 Single values.

  • Two matrix types, Matrix3x2, which represents a 3x2 matrix, and Matrix4x4, which represents a 4x4 matrix.

  • The Plane type, which represents a plane in three-dimensional space.

  • The Quaternion type, which represents a vector that is used to encode three-dimensional physical rotations.

  • The Vector<T> type, which represents a vector of a specified numeric type and provides a broad set of operators that benefit from SIMD support. The count of a Vector<T> instance is fixed, but its value Vector<T>.Count depends on the CPU of the machine, on which code is executed.

    Note

    The Vector<T> type is included with .NET Core and .NET 5+, but not .NET Framework. If you're using .NET Framework, install the System.Numerics.Vectors NuGet package to get access to this type.

The SIMD-enabled types are implemented in such a way that they can be used with non-SIMD-enabled hardware or JIT compilers. To take advantage of SIMD instructions, your 64-bit apps must be run by the runtime that uses the RyuJIT compiler, which is included in .NET Core and in .NET Framework 4.6 and later versions. It adds SIMD support when targeting 64-bit processors.

For more information, see Use SIMD-accelerated numeric types.

See also