Complete Guide to C# BigInteger: Deep Dive with Examples
The BigInteger
type in C# solves a fundamental limitation of fixed-size numeric types like int
, long
, and even Int128
, which are constrained by predefined bit lengths and can easily overflow when handling very large values. These constraints make traditional types unsuitable for scenarios that involve high-precision or unbounded numerical data, such as cryptographic key generation, large-scale scientific simulations, blockchain computations, and certain financial calculations involving massive integer ranges. BigInteger
addresses this by providing an arbitrarily large integer representation that automatically scales to accommodate the size of the number, bounded only by the system’s memory. It is immutable, supports a wide range of arithmetic and bitwise operations, and integrates with .NET’s type system through various interfaces. This flexibility allows developers to work with large numbers safely and efficiently, without resorting to error-prone custom implementations or external libraries.
Table of Contents
- What is BigInteger?
- Namespaces and Assembly
- Constructors
- Key Properties
- Methods
- Operators
- Interfaces Implemented
- Using Interfaces with BigInteger
- Practical Examples
- Performance Considerations
- Custom Structs Based on BigInteger
1. What is BigInteger?
BigInteger
is an immutable type that represents a whole number with arbitrary precision. It grows in size dynamically to accommodate any integer value, regardless of how many digits it contains.
BigInteger big = BigInteger.Parse("123456789123456789123456789123456789");
2. Namespaces and Assembly
To use BigInteger
, you need to include the following:
using System.Numerics;
Ensure your project references the System.Numerics
assembly. This is built-in in .NET Core and .NET 5+, but you may need to add it manually for older projects.
3. Constructors
You can create BigInteger
instances in several ways:
BigInteger a = new BigInteger(12345); // From int
BigInteger b = BigInteger.Parse("9876543210123456789"); // From string
BigInteger c = new BigInteger(new byte[] { 1, 0, 0, 0 }); // From byte array
4. Key Properties
IsZero
– Returns true if the value is 0IsOne
– Returns true if the value is 1IsEven
– Returns true if the number is evenSign
– Returns -1 (negative), 0 (zero), or 1 (positive)
BigInteger num = new BigInteger(-42);
Console.WriteLine(num.Sign); // Output: -1
5. Methods
Parse(string)
– Parses a string to BigIntegerTryParse(string, out BigInteger)
– Safely parses stringToByteArray()
– Converts BigInteger to byte arrayAbs(BigInteger)
– Absolute valuePow(BigInteger, int)
– ExponentiationGreatestCommonDivisor(BigInteger, BigInteger)
using System;
using System.Numerics;
class Program
{
static void Main()
{
BigInteger parsed = BigInteger.Parse("123456789012345678901234567890");
Console.WriteLine($"Parsed: {parsed}");
bool success = BigInteger.TryParse("98765432109876543210", out BigInteger tryParsed);
Console.WriteLine($"TryParsed Success: {success}, Value: {tryParsed}");
byte[] bytes = parsed.ToByteArray();
BigInteger fromBytes = new BigInteger(bytes);
Console.WriteLine($"Restored from bytes: {fromBytes}");
BigInteger absolute = BigInteger.Abs(new BigInteger(-123456));
Console.WriteLine($"Absolute: {absolute}");
BigInteger power = BigInteger.Pow(2, 10);
Console.WriteLine($"2^10: {power}");
BigInteger gcd = BigInteger.GreatestCommonDivisor(48, 18);
Console.WriteLine($"GCD of 48 and 18: {gcd}");
}
}
6. Operators
BigInteger overloads all standard arithmetic and comparison operators:
BigInteger a = 999999999;
BigInteger b = 888888888;
BigInteger sum = a + b;
BigInteger product = a * b;
bool isEqual = a == b;
7. Interfaces Implemented
BigInteger
implements several interfaces:
IComparable
IComparable<BigInteger>
IEquatable<BigInteger>
IFormattable
ISpanFormattable
IConvertible
IBinaryInteger<BigInteger>
(.NET 7+)INumber<BigInteger>
(.NET 7+)
These interfaces enable sorting, equality comparison, formatting, and integration with generic math APIs.
8. Using Interfaces with BigInteger
IComparable / IComparable
Allows comparison and sorting:
List<BigInteger> numbers = new List<BigInteger> { 5, 1000, 50 };
numbers.Sort();
IEquatable
Enables equality checks:
BigInteger a = 123;
BigInteger b = 123;
Console.WriteLine(a.Equals(b)); // True
IFormattable / ISpanFormattable
For string formatting:
BigInteger big = BigInteger.Pow(2, 100);
Console.WriteLine(big.ToString("N0")); // Formatted with commas
IConvertible
Allows conversion to other types:
int converted = ((IConvertible)big).ToInt32(null);
IBinaryInteger and INumber (in .NET 7+)
Used for generic math APIs:
T Square<T>(T value) where T : IBinaryInteger<T> => value * value;
9. Practical Examples
Check if Value Fits in 256-bit
BigInteger value = BigInteger.Parse("115792089237316195423570985008687907853269984665640564039457584007913129639939");
BigInteger max256 = BigInteger.Pow(2, 256) - 1;
if (value > max256)
Console.WriteLine("Too big for 256-bit!");
Convert to and from Byte Array
BigInteger number = new BigInteger(1234567890);
byte[] bytes = number.ToByteArray();
BigInteger restored = new BigInteger(bytes);
10. Performance Considerations
- Slower than primitive types due to dynamic memory and big number math
- Best used only when necessary (e.g., when numbers exceed
long
/Int128
) - Use caching or optimized algorithms for performance-critical tasks
11. Custom Structs Based on BigInteger
You can wrap BigInteger
in a struct to enforce bit-size limits, such as a UInt256
type:
public struct UInt256
{
private BigInteger _value;
private static readonly BigInteger Max = BigInteger.Pow(2, 256) - 1;
public UInt256(BigInteger value)
{
if (value < 0 || value > Max)
throw new ArgumentOutOfRangeException();
_value = value;
}
public static implicit operator BigInteger(UInt256 u) => u._value;
public static explicit operator UInt256(BigInteger b) => new UInt256(b);
public override string ToString() => _value.ToString();
}
Conclusion
BigInteger
is a powerful type for working with huge whole numbers in C#. It provides a rich set of operators, methods, and interfaces, making it flexible for a variety of advanced scenarios. With .NET 7 introducing even more generic math capabilities, BigInteger
now plays nicely in modern C# numerical code. Use it wisely where precision and size matter more than performance.