Code Focused

BigInteger for Astronomically Large Numbers

On VB columnist Joe Kunk explores the new BigInteger structure in .NET 4 and how it lets you work with astronomically large numbers.

The BigInteger structure was introduced in the .NET Framework 4, allowing for an arbitrarily large integer number. Prior to this, the largest integer that could be represented was the int64.MaxValue of 9,223,372,036,854,775,807 or approximately 9.2 x 1018. This certainly has been large enough to represent any integer value I have ever needed. Anything larger is truly an astronomical figure. We explore the new BigInteger structure with a sample program that converts distances in light years to inches.

The figures in this article exceed the precision of most handheld calculators. If you want to follow along and have Windows 7, you can perform these calculations with the Windows 7 calculator in scientific mode.

How many inches in a light year? The speed of light is exactly 299,792,458 meters per second. One year is 31,556,926 seconds. Therefore light travels 9,460,528,412,464,108 meters per year. One meter is 39.3700787401575 inches. I calculate the distance traveled by light in a year to be 372,461,748,522,209,163 inches (3.72 x 1017).

Even a light year in inches is not large enough to require the BigInteger structure. A quick calculation shows that the maximum 64-bit integer can represent a little over 24.763 light years in inches. To give you a little perspective on the size of the numbers we are working with, the space probe Voyager 1 was approximately 16 light-hours away from Earth at the time of this writing, after 33 years of travel. To travel enough inches to require our BigInteger structure, it will have to travel at its current rate of speed for almost another 620,000 years.

Our nearest known star, Proxima Centauri, is 4.22 light-years away, too close for our purposes. Researchers announced on September 29, 2010 that an Earth-sized planet named Gliese 581g was found orbiting in the habitable zone of its red dwarf star and would almost certainly contain life. At only 20 light years away, it is still too close in inches for our BigInteger structure. Recently another planet, named GJ1214b, which is six times the size of Earth and comprised mostly of water, was found orbiting a red dwarf star about 40 light years away. Finally we have a planet far enough away in inches to require our BigInteger structure. So approximately how far away is planet GJ1214b in inches?

BigInteger is found in the System.Numerics namespace. I declare the variable OneLightYearInches as a BigInteger to eliminate the need for casting in the calculation. Note that a BigInteger value cannot be a constant because it is a structure and not a value type. The code below shows our BigInteger light year to inches conversion from the sample program.

        Dim OneLightYearInches As System.Numerics.BigInteger = 372469703661417000

Dim LightYears As System.Numerics.BigInteger = 0
System.Numerics.BigInteger.TryParse(Me.txtLightYears.Text, LightYears)

Me.txtInches.Text = (LightYears * OneLightYearInches).ToString

Our sample program shows planet GJ1214b to be approximately 14,898,788,146,456,680,000 inches (1.4 x 1019) from the Earth. The center of our galaxy, the Milky Way, is about 26,000 light years away, or 9,684,212,295,196,842,000,000 inches (9.6 x 1021). Be careful to count them carefully on your way there!

Now that we can easily compute values in BigInteger, the next question is performance. What is the performance of BigInteger compared to Int64? To determine this, an integer random value is obtained, then added to itself 500 million times, first as an int64 value and then as a BigInteger value, with the calculation times compared. See Figure 1.


[Click on image for larger view.]
Figure 1. Comparing Int64 and BigInteger performance.

The BigInteger calculation loop is over 52 times slower. Both the Int64 and BigInteger values are immutable; a new copy of the value is created in memory each time it is modified. In fact all integral types, including the venerable Integer data type, are immutable. The extra complexity of creating an arbitrarily large number, even when the number is no larger than a standard numeric type, causes the difference in performance. To minimize this performance penalty, especially when modifying BigInteger values in loops, perform as many calculations in standard integral types as possible and assign to the BigInteger structure only when necessary.

Constructing a BigInteger is easy if the initial value is integral within the range of an Int64 value. Both of the following statements are valid:

        Dim Init1 As System.Numerics.BigInteger = 123456789
Dim Init2 As New System.Numerics.BigInteger(123456789)

If the initial value is larger than Int64.MaxValue, the BigInteger can be initialized with the TryParse method, or initialized with a byte array such as:

        Dim byteArray() As Byte = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12}
Dim LargeBigInteger As New System.Numerics.BigInteger(byteArray)

The BigInteger constructor expects the low-order bytes to precede the higher-order bytes in the array.

The ToString() method supports a maximum of 50 significant digits in most cases; any digits beyond that become zero. If your BigInteger value may exceed 50 significant digits, use the ToString("R0") format rather than ToString("N0").

Conclusion
The BigInteger structure, introduced in the .NET Framework 4, represents integers of arbitrary size but should be used only when the Long type is not sufficient, due to the inherent overhead of constructing a variable-sized value. For applications where truly astronomical sized integrals are required, they are now available in managed code with nearly the same ease of use as standard integrals.

About the Author

Joe Kunk is a Microsoft MVP in Visual Basic, three-time president of the Greater Lansing User Group for .NET, and developer for Dart Container Corporation of Mason, Michigan. He's been developing software for over 30 years and has worked in the education, government, financial and manufacturing industries. Kunk's co-authored the book "Professional DevExpress ASP.NET Controls" (Wrox Programmer to Programmer, 2009). He can be reached via email at [email protected].

comments powered by Disqus

Featured

  • Hands On: New VS Code Insiders Build Creates Web Page from Image in Seconds

    New Vision support with GitHub Copilot in the latest Visual Studio Code Insiders build takes a user-supplied mockup image and creates a web page from it in seconds, handling all the HTML and CSS.

  • Naive Bayes Regression Using C#

    Dr. James McCaffrey from Microsoft Research presents a complete end-to-end demonstration of the naive Bayes regression technique, where the goal is to predict a single numeric value. Compared to other machine learning regression techniques, naive Bayes regression is usually less accurate, but is simple, easy to implement and customize, works on both large and small datasets, is highly interpretable, and doesn't require tuning any hyperparameters.

  • VS Code Copilot Previews New GPT-4o AI Code Completion Model

    The 4o upgrade includes additional training on more than 275,000 high-quality public repositories in over 30 popular programming languages, said Microsoft-owned GitHub, which created the original "AI pair programmer" years ago.

  • Microsoft's Rust Embrace Continues with Azure SDK Beta

    "Rust's strong type system and ownership model help prevent common programming errors such as null pointer dereferencing and buffer overflows, leading to more secure and stable code."

  • Xcode IDE from Microsoft Archrival Apple Gets Copilot AI

    Just after expanding the reach of its Copilot AI coding assistant to the open-source Eclipse IDE, Microsoft showcased how it's going even further, providing details about a preview version for the Xcode IDE from archrival Apple.

Subscribe on YouTube

Upcoming Training Events