BigInteger in C# 4.0

One of the great great new features in C# 4.0 that Microsoft added (copied from Java, really) is the addition of an arbitrary-precision integer class, called BigInteger. This class allows you to store an arbitrarily-large integer (more than 232 or 264) and manipulate it as expected.

For example, let’s look at 25! (twenty-five factorial), which is 15511210043330985984000000 (1.5 x 1025). Here’s some code with the standard int class:

int Factorial(int n)
if (n < 0) { throw new ArgumentOutOfRangeException("N must be non-negative"); } else if (n <= 1) { return 1; } else { return n + Factorial(n - 1); } }

Displaying the value of Factorial(25) gives us 2076180480 (2.1 billion), thanks to ints overflowing silently into negative numbers.

On the other hand, if you change the return type to BigInteger, you get the correct value! And this really displays the beauty of C# and Microsoft's strategy; compare it to Java, where you need to create variables, and type values back and forth to get everything in BigIntegers. But not so here--the plus operator is overloaded, int to BigInteger is well understood, so everything just works.

(One caveat is that you need to reference the System.Numerics class, which is not automatically referenced in new C# projects.)

You might ask, how exactly did Microsoft implement the BigInteger class? A quick peek in Reflector shows that they're internally storing it as an array of bits, so you can grow arbitrarily large without too much additional storage. Efficient! And if you run into a case where you can't store a number that large in memory, you'll get an OutOfMemoryException. Snazzy!

Finally, watch out, because BigIntegers are immutable -- just like strings. So be careful how you use them in tight loops.

Chances are you won't run into a case where you need BigInteger anyways (unless you're doing some sort of scientific application), but it's a useful tool to know about. Now, if only C# would include an AtomicInteger class ...

About Ashiq Alibhai, PMP

Ashiq has been coding C# since 2005. A desktop, web, and RIA application developer, he's touched ASP.NET MVC, ActiveRecord, Silverlight, NUnit, and all kinds of exciting .NET technologies. He started C# City in order to accelerate his .NET learning.
This entry was posted in Core .NET, Silverlight, Web, Wndows Forms and tagged , . Bookmark the permalink.

4 Responses to BigInteger in C# 4.0

  1. Wow, this was an excellent post. I am surprised that C# didn’t have BigInteger all this time

  2. Avinash Tauro says:

    I have a BigInteger serialized to a file by a Java program using writeObject of ObjectOutputStream,

    Can I deserialize it in C#.NET. I tried using the java.math and java .io classes of vjslib but I get an exception
    the class does not match the class of the persisted object for cl = java.lang.Number : __SUID = -8742448824652078965, getSUID(cl) = 3166984097235214156

  3. Ashiq Alibhai, PMP says:

    @Avinash, I’m not sure I understand what exactly it is you’re trying to do. Are you taking some BigIntegers from a Java application and importing them into a C# application? If so, you can just output them as text, and import them using BigInteger.Parse(…)

  4. Walter Knopf says:

    Be aware!!!
    The BigInteger in Chew Keong TAN’s library assumes a BigEndian byte ordering, whereas the Microsoft BigInteger uses the Intel (LittleEndian) byte ordering. You might have to use the ArrayReverse(ByteArray) function to make it work for you when you create or read a BigInteger based on a byte array.
    There might be other caveats, but it is nice to use without adding additional copyright notices to your code.

Leave a Reply

Your email address will not be published. Required fields are marked *