# Numerics in .NET

.NET provides a range of numeric integer and floating-point primitives, as well as System.Numerics.BigInteger, which is an integral type with no theoretical upper or lower bound, System.Numerics.Complex, which represents complex numbers, and a set of SIMD-enabled types in the System.Numerics namespace.

## Integer types

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

Type | Signed/Unsigned | Size (in bytes) | Minimum value | Maximum value |
---|---|---|---|---|

System.Byte | Unsigned | 1 | 0 | 255 |

System.Int16 | Signed | 2 | -32,768 | 32,767 |

System.Int32 | Signed | 4 | -2,147,483,648 | 2,147,483,647 |

System.Int64 | Signed | 8 | -9,223,372,036,854,775,808 | 9,223,372,036,854,775,807 |

System.SByte | Signed | 1 | -128 | 127 |

System.UInt16 | Unsigned | 2 | 0 | 65,535 |

System.UInt32 | Unsigned | 4 | 0 | 4,294,967,295 |

System.UInt64 | Unsigned | 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 three primitive floating-point types, which are listed in the following table:

Type | Size (in bytes) | Approximate range | Precision |
---|---|---|---|

System.Single | 4 | ±1.5 x 10^{−45} to ±3.4 x 10^{38} |
~6-9 digits |

System.Double | 8 | ±5.0 × 10^{−324} to ±1.7 × 10^{308} |
~15-17 digits |

System.Decimal | 16 | ±1.0 x 10^{-28} to ±7.9228 x 10^{28} |
28-29 digits |

Both 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 that provides methods which accept arguments of the Single type.

You can also work with the individual bits in Double and Single values by using the System.BitConverter class. The System.Decimal structure has its own methods, Decimal.GetBits and Decimal.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 and Single 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. You should 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 not included into the .NET Framework. You must 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 the .NET Framework 4.6 and later versions. It adds SIMD support when targeting 64-bit processors.