IntX Wiki & Documentation Rss Feedhttp://www.codeplex.com/IntX/Wiki/View.aspx?title=HomeIntX Wiki Rss DescriptionUpdated Wiki: Homehttp://intx.codeplex.com/wikipage?version=39<div class="wikidoc">IntX is an arbitrary precision integers library written in pure C# 2.0 with fast - about O(N * log N) - multiplication/division algorithms implementation. It provides all the basic arithmetic operations on integers, comparing, bitwise shifting etc. It also allows parsing numbers in different bases and converting them to string, also in any base. The advantage of this library is fast multiplication, division and from base/to base conversion algorithms - all the fast versions of the algorithms are based on fast multiplication of big integers using Fast Hartley Transform which runs for O(N * log N * log log N) time instead of classic O(N^2).<br /><br />Project sources are now <a href="https://github.com/devoyster/IntXLib" class="externalLink">hosted on GitHub<span class="externalLinkIcon"></span></a>.<br />
<h3>NuGet</h3>
<a href="http://nuget.org/packages/IntX"><img src="http://i3.codeplex.com/Download?ProjectName=IntX&DownloadId=319975" alt="Install-Package IntX" title="Install-Package IntX" /></a><br />
<h3>Bits of History</h3>
I have written IntX basically because I like big numbers and had some free time. Initial implementation was standard - I was using standard big integers +, -, *, / algorithms from Khuth book. After library was written I've decided to participate in contest held by <a href="http://gotdotnet.ru/" class="externalLink">GotDotNet.ru<span class="externalLinkIcon"></span></a> and received some replies which were saying that my library is too ... usual. Well, it was true, so I've decided to implement some more interesting algorithms in it.<br /><br />I've started with writing multiplication using <a href="http://en.wikipedia.org/wiki/Discrete_Hartley_transform" class="externalLink">Fast Hartley Transform<span class="externalLinkIcon"></span></a> so big integers multiplication time estimate became to be O(N * log N * log log N) (here N is amount of DWORDs in number representation) which was a bit better then O(N^2) with classic algorithm :) Then I saw fast algorithm for transforming from one base to another in Knuth book; it was based on fast multiplication so Parse()/ToString() started working faster - O(N * (log N)^2) instead of O(N^2). Finally division was also optimized (again, with the help of fast multiplication) - became as fast as multiplication.<br /><br />All this happened in 2005 year and in 2008 I've decided to publish this library on CodePlex - maybe it will be useful for someone out there (well, there is not so many similar libraries under .NET; also System.Numeric.BigInteger from .NET FW 3.5 was cancelled). Before publishing it on CodePlex I also made some cosmetic changes in code - used new .NET 2.0 features like generics (to minimize code duplication) and rewritten unit tests to use NUnit (they were previously written for MbUnit which is almost unknown and not used by community).<br />
<h3>Code Example</h3>
Here is the sample of code which uses IntX and calculates 42 in power 1048576 (which is 2^20):<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">using</span> System;
<span style="color:Blue;">using</span> System.Diagnostics;
<span style="color:Blue;">using</span> Oyster.Math;
<span style="color:Blue;">namespace</span> IntxTestApp
{
<span style="color:Blue;">class</span> Program
{
<span style="color:Blue;">static</span> <span style="color:Blue;">void</span> Calc()
{
Stopwatch sw = Stopwatch.StartNew();
IntX.Pow(42, 1 << 20);
sw.Stop();
Console.WriteLine(<span style="color:#A31515;">"{0} ms"</span>, sw.ElapsedMilliseconds);
}
<span style="color:Blue;">static</span> <span style="color:Blue;">void</span> Main()
{
Calc();
IntX.GlobalSettings.MultiplyMode = MultiplyMode.Classic;
Calc();
}
}
}
</pre></div>First Calc() call uses fast multiplication implementation (which is default), second - classic one. On my machine (Win XP Pro SP2, P4 2.8 GHz, 2 GB RAM) first call is <b>70 times</b> faster than the second one (1 second against 68 seconds). Resulting number has 1,702,101 digits; you can get it here: <a href="http://www.codeplex.com/Download?ProjectName=IntX&DownloadId=27428">42pow1048576.txt</a>.<br /><br />Another example is factorial calculation:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">using</span> System;
<span style="color:Blue;">using</span> Oyster.Math;
<span style="color:Blue;">namespace</span> IntxTestApp
{
<span style="color:Blue;">class</span> Program
{
<span style="color:Blue;">static</span> IntX Factorial(IntX n)
{
<span style="color:Blue;">if</span> (n < 0)
{
<span style="color:Blue;">throw</span> <span style="color:Blue;">new</span> ArgumentException(<span style="color:#A31515;">"Can't calculate for negative number."</span>, <span style="color:#A31515;">"n"</span>);
}
<span style="color:Blue;">return</span> n == 0 ? 1 : n * Factorial(n - 1);
}
<span style="color:Blue;">static</span> <span style="color:Blue;">void</span> Main()
{
Console.WriteLine(Factorial(10000));
}
}
}
</pre></div>As you can see, IntX implements all the standard arithmetic operators so its usage is transparent for developer - like if you're working with usual integer.<br />
<h3>FHT and Calculations Precision</h3>
Internally IntX library operates with floating-point numbers when multiplication using FHT is performed so at some point it stops working correctly and loses precision. Luckily, this unpleasant side-effects effects are starting to appear when integer size is about 2^28 bytes i.e. for really huge integers. Anyway, to catch such errors I have added FHT multiplication result validity check into code - it takes N last digits of each big integer, multiplies them using classic approach and then compares last N digits of classic result with last N digits of FHT result (so it's kind of simplified CRC check). If any inconsistency is found then FhtMultiplicationException is thrown; this check can be disabled using global settings.<br />
<h3>Internal Representation and ToString() Performance</h3>
For a really huge integer numbers (like 42 in power 1048576 above) ToString() call can take a very long time to execute. This is because internally IntX big integer is stored as 2^32-base number in uint[] array and to generate decimal string output it should be converted from 2^32 base to decimal base. Such digits storage approach was chosen intentionally - it makes ToString() slower but uses memory efficiently and makes primitive operations on digits faster than power of 10-base storage (which would make ToString() working faster) and I think that usually computations are used more often than ToString().<br />
<h3>Future Plans</h3>
I have no plans to further develop this library - I'm just sharing it with the community.<br />
<h3>System.Numerics.BigInteger in .NET 4.0</h3>
System.Numerics.BigInteger class was introduced in .NET 4.0 so I was interested in performance of this solution. I did some tests (<a href="https://github.com/devoyster/Oyster.Examples/tree/master/Oyster.Examples.IntXTest" class="externalLink">grab test code from GitHub<span class="externalLinkIcon"></span></a>) and it appears that BigInteger has performance in general comparable with IntX on standard operations but starts losing when FHT comes into play (when multiplying really big integers, for example).<br /><br />So internally System.Numerics.BigInteger seems to use standard arbitrary arithmetic algorithms and I am not worrying about IntX library since, due to its use of FHT, it can be times faster for really big integers.<br />
<h3>Comparing IntX Performance to GMP</h3>
While IntX library is fast among other libraries written for .NET it can't really compete with <a href="http://gmplib.org/" class="externalLink">The GNU MP Library<span class="externalLinkIcon"></span></a> - one of the fastest well-known Bignum libraries in the world. GNU MP (or GMP) is written in plain C and Assembly language so it compiles into optimized native code, it also uses fast calculation algorithms - that's why it's very fast. I have compared IntX performance to GMP on basic arithmetic operations and it appeared that GMP is up to 8 times faster than IntX on certain operations. Actually for me it is a good result - IntX written in managed code is still quite fast :) GMP also has comparable performance on huge integers multiplication since, as well as IntX, it implements fast multiplication algorithm using FFT; it's also worth noticing that division for huge integers works few times faster in GMP comparing to IntX. GMP also has support for big floating-point numbers as well as for many numeric algorithms. For tests I was using <a href="http://www.codeplex.com/Download?ProjectName=IntX&DownloadId=102346">libgmp-3.dll</a> GMP 5.0.0 DLL built for Windows using MinGW; I also want to add that my performance comparing was primitive and its results are very approximate.<br /><br />So if you need to perform a lot of operations with big integers and must get the fastest possible speed from them then I'd suggest you using <a href="http://gmplib.org/" class="externalLink">GMP<span class="externalLinkIcon"></span></a> (distributed under LGPL license); if you work in Windows you can build it with Cygwin/MinGW or use some GMP Windows-friendly port like <a href="http://www.mpir.org/" class="externalLink">MPIR<span class="externalLinkIcon"></span></a>. However, if 8x speed loss on some operations is okay for your project and/or you don't want to include unmanaged code into your application then IntX should be enough for you.<br /><br />Btw, using GMP from C# is quite easy because there are GMP C#-wrappers available <a href="http://www.emilstefanov.net/Projects/GnuMpDotNet/" class="externalLink">here<span class="externalLinkIcon"></span></a> (this one I was using for tests) and <a href="http://gnumpnet.codeplex.com/" class="externalLink">there<span class="externalLinkIcon"></span></a>. But be careful with them - both wrappers I saw are releasing unmanaged resource they are referring (which is memory) only in Finalize() method override and not implementing IDisposable so you can end up with unexpected OutOfMemoryException as I did.</div><div class="ClearBoth"></div>OysterSun, 08 Jan 2012 18:12:22 GMTUpdated Wiki: Home 20120108061222PUpdated Wiki: Homehttp://intx.codeplex.com/wikipage?version=38<div class="wikidoc">IntX is an arbitrary precision integers library written in pure C# 2.0 with fast - about O(N * log N) - multiplication/division algorithms implementation. It provides all the basic arithmetic operations on integers, comparing, bitwise shifting etc. It also allows parsing numbers in different bases and converting them to string, also in any base. The advantage of this library is fast multiplication, division and from base/to base conversion algorithms - all the fast versions of the algorithms are based on fast multiplication of big integers using Fast Hartley Transform which runs for O(N * log N * log log N) time instead of classic O(N^2).<br /><br />Project sources are now <a href="https://github.com/devoyster/IntXLib" class="externalLink">hosted on GitHub<span class="externalLinkIcon"></span></a>.<br />
<h3>NuGet</h3>
<a href="http://nuget.org/packages/IntX"><img src="http://i3.codeplex.com/Download?ProjectName=IntX&DownloadId=319975" alt="Install-Package IntX" title="Install-Package IntX" /></a><br />
<h3>Bits of History</h3>
I have written IntX basically because I like big numbers and had some free time. Initial implementation was standard - I was using standard big integers +, -, *, / algorithms from Khuth book. After library was written I've decided to participate in contest held by <a href="http://gotdotnet.ru/" class="externalLink">GotDotNet.ru<span class="externalLinkIcon"></span></a> and received some replies which were saying that my library is too ... usual. Well, it was true, so I've decided to implement some more interesting algorithms in it.<br /><br />I've started with writing multiplication using <a href="http://en.wikipedia.org/wiki/Discrete_Hartley_transform" class="externalLink">Fast Hartley Transform<span class="externalLinkIcon"></span></a> so big integers multiplication time estimate became to be O(N * log N * log log N) (here N is amount of DWORDs in number representation) which was a bit better then O(N^2) with classic algorithm :) Then I saw fast algorithm for transforming from one base to another in Knuth book; it was based on fast multiplication so Parse()/ToString() started working faster - O(N * (log N)^2) instead of O(N^2). Finally division was also optimized (again, with the help of fast multiplication) - became as fast as multiplication.<br /><br />All this happened in 2005 year and in 2008 I've decided to publish this library on CodePlex - maybe it will be useful for someone out there (well, there is not so many similar libraries under .NET; also System.Numeric.BigInteger from .NET FW 3.5 was cancelled). Before publishing it on CodePlex I also made some cosmetic changes in code - used new .NET 2.0 features like generics (to minimize code duplication) and rewritten unit tests to use NUnit (they were previously written for MbUnit which is almost unknown and not used by community).<br />
<h3>Code Example</h3>
Here is the sample of code which uses IntX and calculates 42 in power 1048576 (which is 2^20):<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">using</span> System;
<span style="color:Blue;">using</span> System.Diagnostics;
<span style="color:Blue;">using</span> Oyster.Math;
<span style="color:Blue;">namespace</span> IntxTestApp
{
<span style="color:Blue;">class</span> Program
{
<span style="color:Blue;">static</span> <span style="color:Blue;">void</span> Calc()
{
Stopwatch sw = Stopwatch.StartNew();
IntX.Pow(42, 1 << 20);
sw.Stop();
Console.WriteLine(<span style="color:#A31515;">"{0} ms"</span>, sw.ElapsedMilliseconds);
}
<span style="color:Blue;">static</span> <span style="color:Blue;">void</span> Main()
{
Calc();
IntX.GlobalSettings.MultiplyMode = MultiplyMode.Classic;
Calc();
}
}
}
</pre></div>First Calc() call uses fast multiplication implementation (which is default), second - classic one. On my machine (Win XP Pro SP2, P4 2.8 GHz, 2 GB RAM) first call is <b>70 times</b> faster than the second one (1 second against 68 seconds). Resulting number has 1,702,101 digits; you can get it here: <a href="http://www.codeplex.com/Download?ProjectName=IntX&DownloadId=27428">42pow1048576.txt</a>.<br /><br />Another example is factorial calculation:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">using</span> System;
<span style="color:Blue;">using</span> Oyster.Math;
<span style="color:Blue;">namespace</span> IntxTestApp
{
<span style="color:Blue;">class</span> Program
{
<span style="color:Blue;">static</span> IntX Factorial(IntX n)
{
<span style="color:Blue;">if</span> (n < 0)
{
<span style="color:Blue;">throw</span> <span style="color:Blue;">new</span> ArgumentException(<span style="color:#A31515;">"Can't calculate for negative number."</span>, <span style="color:#A31515;">"n"</span>);
}
<span style="color:Blue;">return</span> n == 0 ? 1 : n * Factorial(n - 1);
}
<span style="color:Blue;">static</span> <span style="color:Blue;">void</span> Main()
{
Console.WriteLine(Factorial(10000));
}
}
}
</pre></div>As you can see, IntX implements all the standard arithmetic operators so its usage is transparent for developer - like if you're working with usual integer.<br />
<h3>FHT and Calculations Precision</h3>
Internally IntX library operates with floating-point numbers when multiplication using FHT is performed so at some point it stops working correctly and loses precision. Luckily, this unpleasant side-effects effects are starting to appear when integer size is about 2^28 bytes i.e. for really huge integers. Anyway, to catch such errors I have added FHT multiplication result validity check into code - it takes N last digits of each big integer, multiplies them using classic approach and then compares last N digits of classic result with last N digits of FHT result (so it's kind of simplified CRC check). If any inconsistency is found then FhtMultiplicationException is thrown; this check can be disabled using global settings.<br />
<h3>Internal Representation and ToString() Performance</h3>
For a really huge integer numbers (like 42 in power 1048576 above) ToString() call can take a very long time to execute. This is because internally IntX big integer is stored as 2^32-base number in uint[] array and to generate decimal string output it should be converted from 2^32 base to decimal base. Such digits storage approach was chosen intentionally - it makes ToString() slower but uses memory efficiently and makes primitive operations on digits faster than power of 10-base storage (which would make ToString() working faster) and I think that usually computations are used more often than ToString().<br />
<h3>Future Plans</h3>
I have no plans to further develop this library - I'm just sharing it with the community.<br />
<h3>System.Numerics.BigInteger in .NET 4.0</h3>
System.Numerics.BigInteger class was introduced in .NET 4.0 so I was interested in performance of this solution. I did some tests and it appears that BigInteger has performance in general comparable with IntX on standard operations but starts losing when FHT comes into play (when multiplying really big integers, for example).<br /><br />So internally System.Numerics.BigInteger seems to use standard arbitrary arithmetic algorithms and I am not worrying about IntX library since, due to its use of FHT, it can be times faster for really big integers.<br />
<h3>Comparing IntX Performance to GMP</h3>
While IntX library is fast among other libraries written for .NET it can't really compete with <a href="http://gmplib.org/" class="externalLink">The GNU MP Library<span class="externalLinkIcon"></span></a> - one of the fastest well-known Bignum libraries in the world. GNU MP (or GMP) is written in plain C and Assembly language so it compiles into optimized native code, it also uses fast calculation algorithms - that's why it's very fast. I have compared IntX performance to GMP on basic arithmetic operations and it appeared that GMP is up to 8 times faster than IntX on certain operations. Actually for me it is a good result - IntX written in managed code is still quite fast :) GMP also has comparable performance on huge integers multiplication since, as well as IntX, it implements fast multiplication algorithm using FFT; it's also worth noticing that division for huge integers works few times faster in GMP comparing to IntX. GMP also has support for big floating-point numbers as well as for many numeric algorithms. For tests I was using <a href="http://www.codeplex.com/Download?ProjectName=IntX&DownloadId=102346">libgmp-3.dll</a> GMP 5.0.0 DLL built for Windows using MinGW; I also want to add that my performance comparing was primitive and its results are very approximate.<br /><br />So if you need to perform a lot of operations with big integers and must get the fastest possible speed from them then I'd suggest you using <a href="http://gmplib.org/" class="externalLink">GMP<span class="externalLinkIcon"></span></a> (distributed under LGPL license); if you work in Windows you can build it with Cygwin/MinGW or use some GMP Windows-friendly port like <a href="http://www.mpir.org/" class="externalLink">MPIR<span class="externalLinkIcon"></span></a>. However, if 8x speed loss on some operations is okay for your project and/or you don't want to include unmanaged code into your application then IntX should be enough for you.<br /><br />Btw, using GMP from C# is quite easy because there are GMP C#-wrappers available <a href="http://www.emilstefanov.net/Projects/GnuMpDotNet/" class="externalLink">here<span class="externalLinkIcon"></span></a> (this one I was using for tests) and <a href="http://gnumpnet.codeplex.com/" class="externalLink">there<span class="externalLinkIcon"></span></a>. But be careful with them - both wrappers I saw are releasing unmanaged resource they are referring (which is memory) only in Finalize() method override and not implementing IDisposable so you can end up with unexpected OutOfMemoryException as I did.</div><div class="ClearBoth"></div>OysterFri, 30 Dec 2011 14:21:44 GMTUpdated Wiki: Home 20111230022144PUpdated Wiki: Homehttp://intx.codeplex.com/wikipage?version=37<div class="wikidoc">IntX is an arbitrary precision integers library written in pure C# 2.0 with fast - about O(N * log N) - multiplication/division algorithms implementation. It provides all the basic arithmetic operations on integers, comparing, bitwise shifting etc. It also allows parsing numbers in different bases and converting them to string, also in any base. The advantage of this library is fast multiplication, division and from base/to base conversion algorithms - all the fast versions of the algorithms are based on fast multiplication of big integers using Fast Hartley Transform which runs for O(N * log N * log log N) time instead of classic O(N^2).<br /><br />Project sources are now <a href="https://github.com/devoyster/IntXLib" class="externalLink">hosted on GitHub<span class="externalLinkIcon"></span></a>.<br />
<h3>NuGet</h3>
<a href="http://nuget.org/packages/IntX"><img src="http://i3.codeplex.com/Download?ProjectName=IntX&DownloadId=319975" alt="Install-Package IntX" title="Install-Package IntX" /></a><br />
<h3>Bits of History</h3>
I have written IntX basically because I like big numbers and had some free time. Initial implementation was standard - I was using standard big integers +, -, *, / algorithms from Khuth book. After library was written I've decided to participate in contest held by <a href="http://gotdotnet.ru/" class="externalLink">GotDotNet.ru<span class="externalLinkIcon"></span></a> and received some replies which were saying that my library is too ... usual. Well, it was true, so I've decided to implement some more interesting algorithms in it.<br /><br />I've started with writing multiplication using <a href="http://en.wikipedia.org/wiki/Discrete_Hartley_transform" class="externalLink">Fast Hartley Transform<span class="externalLinkIcon"></span></a> so big integers multiplication time estimate became to be O(N * log N * log log N) (here N is amount of DWORDs in number representation) which was a bit better then O(N^2) with classic algorithm :) Then I saw fast algorithm for transforming from one base to another in Knuth book; it was based on fast multiplication so Parse()/ToString() started working faster - O(N * (log N)^2) instead of O(N^2). Finally division was also optimized (again, with the help of fast multiplication) - became as fast as multiplication.<br /><br />All this happened in 2005 year and in 2008 I've decided to publish this library on CodePlex - maybe it will be useful for someone out there (well, there is not so many similar libraries under .NET; also System.Numeric.BigInteger from .NET FW 3.5 was cancelled). Before publishing it on CodePlex I also made some cosmetic changes in code - used new .NET 2.0 features like generics (to minimize code duplication) and rewritten unit tests to use NUnit (they were previously written for MbUnit which is almost unknown and not used by community).<br />
<h3>Code Example</h3>
Here is the sample of code which uses IntX and calculates 42 in power 1048576 (which is 2^20):<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">using</span> System;
<span style="color:Blue;">using</span> System.Diagnostics;
<span style="color:Blue;">using</span> Oyster.Math;
<span style="color:Blue;">namespace</span> IntxTestApp
{
<span style="color:Blue;">class</span> Program
{
<span style="color:Blue;">static</span> <span style="color:Blue;">void</span> Calc()
{
Stopwatch sw = Stopwatch.StartNew();
IntX.Pow(42, 1 << 20);
sw.Stop();
Console.WriteLine(<span style="color:#A31515;">"{0} ms"</span>, sw.ElapsedMilliseconds);
}
<span style="color:Blue;">static</span> <span style="color:Blue;">void</span> Main()
{
Calc();
IntX.GlobalSettings.MultiplyMode = MultiplyMode.Classic;
Calc();
}
}
}
</pre></div>First Calc() call uses fast multiplication implementation (which is default), second - classic one. On my machine (Win XP Pro SP2, P4 2.8 GHz, 2 GB RAM) first call is <b>70 times</b> faster than the second one (1 second against 68 seconds). Resulting number has 1,702,101 digits; you can get it here: <a href="http://www.codeplex.com/Download?ProjectName=IntX&DownloadId=27428">42pow1048576.txt</a>.<br /><br />Another example is factorial calculation:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">using</span> System;
<span style="color:Blue;">using</span> Oyster.Math;
<span style="color:Blue;">namespace</span> IntxTestApp
{
<span style="color:Blue;">class</span> Program
{
<span style="color:Blue;">static</span> IntX Factorial(IntX n)
{
<span style="color:Blue;">if</span> (n < 0)
{
<span style="color:Blue;">throw</span> <span style="color:Blue;">new</span> ArgumentException(<span style="color:#A31515;">"Can't calculate factorial for negative number."</span>, <span style="color:#A31515;">"n"</span>);
}
<span style="color:Blue;">return</span> n == 0 ? 1 : n * Factorial(n - 1);
}
<span style="color:Blue;">static</span> <span style="color:Blue;">void</span> Main()
{
Console.WriteLine(Factorial(10000));
}
}
}
</pre></div>As you can see, IntX implements all the standard arithmetic operators so its usage is transparent for developer - like if you're working with usual integer.<br />
<h3>FHT and Calculations Precision</h3>
Internally IntX library operates with floating-point numbers when multiplication using FHT is performed so at some point it stops working correctly and loses precision. Luckily, this unpleasant side-effects effects are starting to appear when integer size is about 2^28 bytes i.e. for really huge integers. Anyway, to catch such errors I have added FHT multiplication result validity check into code - it takes N last digits of each big integer, multiplies them using classic approach and then compares last N digits of classic result with last N digits of FHT result (so it's kind of simplified CRC check). If any inconsistency is found then FhtMultiplicationException is thrown; this check can be disabled using global settings.<br />
<h3>Internal Representation and ToString() Performance</h3>
For a really huge integer numbers (like 42 in power 1048576 above) ToString() call can take a very long time to execute. This is because internally IntX big integer is stored as 2^32-base number in uint[] array and to generate decimal string output it should be converted from 2^32 base to decimal base. Such digits storage approach was chosen intentionally - it makes ToString() slower but uses memory efficiently and makes primitive operations on digits faster than power of 10-base storage (which would make ToString() working faster) and I think that usually computations are used more often than ToString().<br />
<h3>Future Plans</h3>
I have no plans to further develop this library - I'm just sharing it with the community.<br />
<h3>System.Numerics.BigInteger in .NET 4.0</h3>
System.Numerics.BigInteger class was introduced in .NET 4.0 so I was interested in performance of this solution. I did some tests and it appears that BigInteger has performance in general comparable with IntX on standard operations but starts losing when FHT comes into play (when multiplying really big integers, for example).<br /><br />So internally System.Numerics.BigInteger seems to use standard arbitrary arithmetic algorithms and I am not worrying about IntX library since, due to its use of FHT, it can be times faster for really big integers.<br />
<h3>Comparing IntX Performance to GMP</h3>
While IntX library is fast among other libraries written for .NET it can't really compete with <a href="http://gmplib.org/" class="externalLink">The GNU MP Library<span class="externalLinkIcon"></span></a> - one of the fastest well-known Bignum libraries in the world. GNU MP (or GMP) is written in plain C and Assembly language so it compiles into optimized native code, it also uses fast calculation algorithms - that's why it's very fast. I have compared IntX performance to GMP on basic arithmetic operations and it appeared that GMP is up to 8 times faster than IntX on certain operations. Actually for me it is a good result - IntX written in managed code is still quite fast :) GMP also has comparable performance on huge integers multiplication since, as well as IntX, it implements fast multiplication algorithm using FFT; it's also worth noticing that division for huge integers works few times faster in GMP comparing to IntX. GMP also has support for big floating-point numbers as well as for many numeric algorithms. For tests I was using <a href="http://www.codeplex.com/Download?ProjectName=IntX&DownloadId=102346">libgmp-3.dll</a> GMP 5.0.0 DLL built for Windows using MinGW; I also want to add that my performance comparing was primitive and its results are very approximate.<br /><br />So if you need to perform a lot of operations with big integers and must get the fastest possible speed from them then I'd suggest you using <a href="http://gmplib.org/" class="externalLink">GMP<span class="externalLinkIcon"></span></a> (distributed under LGPL license); if you work in Windows you can build it with Cygwin/MinGW or use some GMP Windows-friendly port like <a href="http://www.mpir.org/" class="externalLink">MPIR<span class="externalLinkIcon"></span></a>. However, if 8x speed loss on some operations is okay for your project and/or you don't want to include unmanaged code into your application then IntX should be enough for you.<br /><br />Btw, using GMP from C# is quite easy because there are GMP C#-wrappers available <a href="http://www.emilstefanov.net/Projects/GnuMpDotNet/" class="externalLink">here<span class="externalLinkIcon"></span></a> (this one I was using for tests) and <a href="http://gnumpnet.codeplex.com/" class="externalLink">there<span class="externalLinkIcon"></span></a>. But be careful with them - both wrappers I saw are releasing unmanaged resource they are referring (which is memory) only in Finalize() method override and not implementing IDisposable so you can end up with unexpected OutOfMemoryException as I did.</div><div class="ClearBoth"></div>OysterFri, 30 Dec 2011 14:20:55 GMTUpdated Wiki: Home 20111230022055PUpdated Wiki: Homehttp://intx.codeplex.com/wikipage?version=36<div class="wikidoc"><h2><a href="http://nuget.org/packages/IntX" class="externalLink">Download IntX 1.0.0.0 from NuGet<span class="externalLinkIcon"></span></a></h2>
<b>Project Description</b><br />IntX is an arbitrary precision integers library written in pure C# 2.0 with fast - about O(N * log N) - multiplication/division algorithms implementation. It provides all the basic arithmetic operations on integers, comparing, bitwise shifting etc. It also allows parsing numbers in different bases and converting them to string, also in any base. The advantage of this library is fast multiplication, division and from base/to base conversion algorithms - all the fast versions of the algorithms are based on fast multiplication of big integers using Fast Hartley Transform which runs for O(N * log N * log log N) time instead of classic O(N^2).<br /><br />Project sources are now <a href="https://github.com/devoyster/IntXLib" class="externalLink">hosted on GitHub<span class="externalLinkIcon"></span></a>.<br /><br /><b>Bits of History</b><br />I have written IntX basically because I like big numbers and had some free time. Initial implementation was standard - I was using standard big integers +, -, *, / algorithms from Khuth book. After library was written I've decided to participate in contest held by <a href="http://gotdotnet.ru/" class="externalLink">GotDotNet.ru<span class="externalLinkIcon"></span></a> and received some replies which were saying that my library is too ... usual. Well, it was true, so I've decided to implement some more interesting algorithms in it.<br /><br />I've started with writing multiplication using <a href="http://en.wikipedia.org/wiki/Discrete_Hartley_transform" class="externalLink">Fast Hartley Transform<span class="externalLinkIcon"></span></a> so big integers multiplication time estimate became to be O(N * log N * log log N) (here N is amount of DWORDs in number representation) which was a bit better then O(N^2) with classic algorithm :) Then I saw fast algorithm for transforming from one base to another in Knuth book; it was based on fast multiplication so Parse()/ToString() started working faster - O(N * (log N)^2) instead of O(N^2). Finally division was also optimized (again, with the help of fast multiplication) - became as fast as multiplication.<br /><br />All this happened in 2005 year and in 2008 I've decided to publish this library on CodePlex - maybe it will be useful for someone out there (well, there is not so many similar libraries under .NET; also System.Numeric.BigInteger from .NET FW 3.5 was cancelled). Before publishing it on CodePlex I also made some cosmetic changes in code - used new .NET 2.0 features like generics (to minimize code duplication) and rewritten unit tests to use NUnit (they were previously written for MbUnit which is almost unknown and not used by community).<br /><br /><b>Code Example</b><br />Here is the sample of code which uses IntX and calculates 42 in power 1048576 (which is 2^20):<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">using</span> System;
<span style="color:Blue;">using</span> System.Diagnostics;
<span style="color:Blue;">using</span> Oyster.Math;
<span style="color:Blue;">namespace</span> IntxTestApp
{
<span style="color:Blue;">class</span> Program
{
<span style="color:Blue;">static</span> <span style="color:Blue;">void</span> Calc()
{
Stopwatch sw = Stopwatch.StartNew();
IntX.Pow(42, 1 << 20);
sw.Stop();
Console.WriteLine(<span style="color:#A31515;">"{0} ms"</span>, sw.ElapsedMilliseconds);
}
<span style="color:Blue;">static</span> <span style="color:Blue;">void</span> Main()
{
Calc();
IntX.GlobalSettings.MultiplyMode = MultiplyMode.Classic;
Calc();
}
}
}
</pre></div>First Calc() call uses fast multiplication implementation (which is default), second - classic one. On my machine (Win XP Pro SP2, P4 2.8 GHz, 2 GB RAM) first call is <b>70 times</b> faster than the second one (1 second against 68 seconds). Resulting number has 1,702,101 digits; you can get it here: <a href="http://www.codeplex.com/Download?ProjectName=IntX&DownloadId=27428">42pow1048576.txt</a>.<br /><br />Another example is factorial calculation:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">using</span> System;
<span style="color:Blue;">using</span> Oyster.Math;
<span style="color:Blue;">namespace</span> IntxTestApp
{
<span style="color:Blue;">class</span> Program
{
<span style="color:Blue;">static</span> IntX Factorial(IntX n)
{
<span style="color:Blue;">if</span> (n < 0)
{
<span style="color:Blue;">throw</span> <span style="color:Blue;">new</span> ArgumentException(<span style="color:#A31515;">"Can't calculate factorial for negative number."</span>, <span style="color:#A31515;">"n"</span>);
}
<span style="color:Blue;">return</span> n == 0 ? 1 : n * Factorial(n - 1);
}
<span style="color:Blue;">static</span> <span style="color:Blue;">void</span> Main()
{
Console.WriteLine(Factorial(10000));
}
}
}
</pre></div>As you can see, IntX implements all the standard arithmetic operators so its usage is transparent for developer - like if you're working with usual integer.<br /><br /><b>FHT and Calculations Precision</b><br />Internally IntX library operates with floating-point numbers when multiplication using FHT is performed so at some point it stops working correctly and loses precision. Luckily, this unpleasant side-effects effects are starting to appear when integer size is about 2^28 bytes i.e. for really huge integers. Anyway, to catch such errors I have added FHT multiplication result validity check into code - it takes N last digits of each big integer, multiplies them using classic approach and then compares last N digits of classic result with last N digits of FHT result (so it's kind of simplified CRC check). If any inconsistency is found then FhtMultiplicationException is thrown; this check can be disabled using global settings.<br /><br /><b>Internal Representation and ToString() Performance</b><br />For a really huge integer numbers (like 42 in power 1048576 above) ToString() call can take a very long time to execute. This is because internally IntX big integer is stored as 2^32-base number in uint[] array and to generate decimal string output it should be converted from 2^32 base to decimal base. Such digits storage approach was chosen intentionally - it makes ToString() slower but uses memory efficiently and makes primitive operations on digits faster than power of 10-base storage (which would make ToString() working faster) and I think that usually computations are used more often than ToString().<br /><br /><b>Future Plans</b><br />I have no plans to further develop this library - I'm just sharing it with the community.<br /><br /><b>System.Numerics.BigInteger in .NET 4.0</b><br />System.Numerics.BigInteger class was introduced in .NET 4.0 so I was interested in performance of this solution. I did some tests and it appears that BigInteger has performance in general comparable with IntX on standard operations but starts losing when FHT comes into play (when multiplying really big integers, for example).<br /><br />So internally System.Numerics.BigInteger seems to use standard arbitrary arithmetic algorithms and I am not worrying about IntX library since, due to its use of FHT, it can be times faster for really big integers.<br /><br /><b>Comparing IntX Performance to GMP</b><br />While IntX library is fast among other libraries written for .NET it can't really compete with <a href="http://gmplib.org/" class="externalLink">The GNU MP Library<span class="externalLinkIcon"></span></a> - one of the fastest well-known Bignum libraries in the world. GNU MP (or GMP) is written in plain C and Assembly language so it compiles into optimized native code, it also uses fast calculation algorithms - that's why it's very fast. I have compared IntX performance to GMP on basic arithmetic operations and it appeared that GMP is up to 8 times faster than IntX on certain operations. Actually for me it is a good result - IntX written in managed code is still quite fast :) GMP also has comparable performance on huge integers multiplication since, as well as IntX, it implements fast multiplication algorithm using FFT; it's also worth noticing that division for huge integers works few times faster in GMP comparing to IntX. GMP also has support for big floating-point numbers as well as for many numeric algorithms. For tests I was using <a href="http://www.codeplex.com/Download?ProjectName=IntX&DownloadId=102346">libgmp-3.dll</a> GMP 5.0.0 DLL built for Windows using MinGW; I also want to add that my performance comparing was primitive and its results are very approximate.<br /><br />So if you need to perform a lot of operations with big integers and must get the fastest possible speed from them then I'd suggest you using <a href="http://gmplib.org/" class="externalLink">GMP<span class="externalLinkIcon"></span></a> (distributed under LGPL license); if you work in Windows you can build it with Cygwin/MinGW or use some GMP Windows-friendly port like <a href="http://www.mpir.org/" class="externalLink">MPIR<span class="externalLinkIcon"></span></a>. However, if 8x speed loss on some operations is okay for your project and/or you don't want to include unmanaged code into your application then IntX should be enough for you.<br /><br />Btw, using GMP from C# is quite easy because there are GMP C#-wrappers available <a href="http://www.emilstefanov.net/Projects/GnuMpDotNet/" class="externalLink">here<span class="externalLinkIcon"></span></a> (this one I was using for tests) and <a href="http://gnumpnet.codeplex.com/" class="externalLink">there<span class="externalLinkIcon"></span></a>. But be careful with them - both wrappers I saw are releasing unmanaged resource they are referring (which is memory) only in Finalize() method override and not implementing IDisposable so you can end up with unexpected OutOfMemoryException as I did.</div><div class="ClearBoth"></div>OysterFri, 30 Dec 2011 09:39:38 GMTUpdated Wiki: Home 20111230093938AUpdated Wiki: Homehttp://intx.codeplex.com/wikipage?version=35<div class="wikidoc"><h2><a href="http://nuget.org/packages/IntX" class="externalLink">Download IntX 1.0.0.0 from NuGet<span class="externalLinkIcon"></span></a></h2>
<b>Project Description</b><br />IntX is an arbitrary precision integers library written in pure C# 2.0 with fast - about O(N * log N) - multiplication/division algorithms implementation. It provides all the basic arithmetic operations on integers, comparing, bitwise shifting etc. It also allows parsing numbers in different bases and converting them to string, also in any base. The advantage of this library is fast multiplication, division and from base/to base conversion algorithms - all the fast versions of the algorithms are based on fast multiplication of big integers using Fast Hartley Transform which runs for O(N * log N * log log N) time instead of classic O(N^2).<br /><br />Project sources are now <a href="https://github.com/devoyster/IntXLib" class="externalLink">hosted on GitHub<span class="externalLinkIcon"></span></a>.<br /><br /><b>Bits of History</b><br />I have written IntX basically because I like big numbers and had some free time. Initial implementation was standard - I was using standard big integers +, -, *, / algorithms from Khuth book. After library was written I've decided to participate in contest held by <a href="http://gotdotnet.ru/" class="externalLink">GotDotNet.ru<span class="externalLinkIcon"></span></a> and received some replies which were saying that my library is too ... usual. Well, it was true, so I've decided to implement some more interesting algorithms in it.<br /><br />I've started with writing multiplication using <a href="http://en.wikipedia.org/wiki/Discrete_Hartley_transform" class="externalLink">Fast Hartley Transform<span class="externalLinkIcon"></span></a> so big integers multiplication time estimate became to be O(N * log N * log log N) (here N is amount of DWORDs in number representation) which was a bit better then O(N^2) with classic algorithm :) Then I saw fast algorithm for transforming from one base to another in Knuth book; it was based on fast multiplication so Parse()/ToString() started working faster - O(N * (log N)^2) instead of O(N^2). Finally division was also optimized (again, with the help of fast multiplication) - became as fast as multiplication.<br /><br />All this happened in 2005 year and in 2008 I've decided to publish this library on CodePlex - maybe it will be useful for someone out there (well, there is not so many similar libraries under .NET; also System.Numeric.BigInteger from .NET FW 3.5 was cancelled). Before publishing it on CodePlex I also made some cosmetic changes in code - used new .NET 2.0 features like generics (to minimize code duplication) and rewritten unit tests to use NUnit (they were previously written for MbUnit which is almost unknown and not used by community).<br /><br /><b>Code Example</b><br />Here is the sample of code which uses IntX and calculates 42 in power 1048576 (which is 2^20):<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">using</span> System;
<span style="color:Blue;">using</span> System.Diagnostics;
<span style="color:Blue;">using</span> Oyster.Math;
<span style="color:Blue;">namespace</span> IntxTestApp
{
<span style="color:Blue;">class</span> Program
{
<span style="color:Blue;">static</span> <span style="color:Blue;">void</span> Calc()
{
Stopwatch sw = Stopwatch.StartNew();
IntX.Pow(42, 1 << 20);
sw.Stop();
Console.WriteLine(<span style="color:#A31515;">"{0} ms"</span>, sw.ElapsedMilliseconds);
}
<span style="color:Blue;">static</span> <span style="color:Blue;">void</span> Main()
{
Calc();
IntX.GlobalSettings.MultiplyMode = MultiplyMode.Classic;
Calc();
}
}
}
</pre></div>First Calc() call uses fast multiplication implementation (which is default), second - classic one. On my machine (Win XP Pro SP2, P4 2.8 GHz, 2 GB RAM) first call is <b>70 times</b> faster than the second one (1 second against 68 seconds). Resulting number has 1,702,101 digits; you can get it here: <a href="http://www.codeplex.com/Download?ProjectName=IntX&DownloadId=27428">42pow1048576.txt</a>.<br /><br />Another example is factorial calculation:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">using</span> System;
<span style="color:Blue;">using</span> Oyster.Math;
<span style="color:Blue;">namespace</span> IntxTestApp
{
<span style="color:Blue;">class</span> Program
{
<span style="color:Blue;">static</span> IntX Factorial(IntX n)
{
<span style="color:Blue;">if</span> (n < 0)
{
<span style="color:Blue;">throw</span> <span style="color:Blue;">new</span> ArgumentException(<span style="color:#A31515;">"Can't calculate factorial for negative number."</span>, <span style="color:#A31515;">"n"</span>);
}
<span style="color:Blue;">return</span> n == 0 ? 1 : n * Factorial(n - 1);
}
<span style="color:Blue;">static</span> <span style="color:Blue;">void</span> Main()
{
Console.WriteLine(Factorial(10000));
}
}
}
</pre></div>As you can see, IntX implements all the standard arithmetic operators so its usage is transparent for developer - like if you're working with usual integer.<br /><br /><b>FHT and Calculations Precision</b><br />Internally IntX library operates with floating-point numbers when multiplication using FHT is performed so at some point it stops working correctly and loses precision. Luckily, this unpleasant side-effects effects are starting to appear when integer size is about 2^28 bytes i.e. for really huge integers. Anyway, to catch such errors I have added FHT multiplication result validity check into code - it takes N last digits of each big integer, multiplies them using classic approach and then compares last N digits of classic result with last N digits of FHT result (so it's kind of simplified CRC check). If any inconsistency is found then FhtMultiplicationException is thrown; this check can be disabled using global settings.<br /><br /><b>Internal Representation and ToString() Performance</b><br />For a really huge integer numbers (like 42 in power 1048576 above) ToString() call can take a very long time to execute. This is because internally IntX big integer is stored as 2^32-base number in uint[] array and to generate decimal string output it should be converted from 2^32 base to decimal base. Such digits storage approach was chosen intentionally - it makes ToString() slower but uses memory efficiently and makes primitive operations on digits faster than power of 10-base storage (which would make ToString() working faster) and I think that usually computations are used more often than ToString().<br /><br /><b>Future Plans</b><br />I have no plans to further develop this library - I'm just sharing it with the community.<br /><br /><b>System.Numerics.BigInteger in .NET 4.0</b><br />System.Numerics.BigInteger class was introduced in .NET 4.0 so I was interested in performance of this solution. I did some tests and it appears that BigInteger has performance in general comparable with IntX on standard operations but starts losing when FHT comes into play (when multiplying really big integers, for example).<br /><br />So internally System.Numerics.BigInteger seems to use standard arbitrary arithmetic algorithms and I am not worrying about IntX library since, due to its use of FHT, it can be times faster for really big integers.<br /><br /><b>Comparing IntX Performance to GMP</b><br />While IntX library is fast among other libraries written for .NET it can't really compete with <a href="http://gmplib.org/" class="externalLink">The GNU MP Library<span class="externalLinkIcon"></span></a> - one of the fastest well-known Bignum libraries in the world. GNU MP (or GMP) is written in plain C and Assembly language so it compiles into optimized native code, it also uses fast calculation algorithms - that's why it's very fast. I have compared IntX performance to GMP on basic arithmetic operations and it appeared that GMP is up to 8 times faster than IntX on certain operations. Actually for me it is a good result - IntX written in managed code is still quite fast :) GMP also has comparable performance on huge integers multiplication since, as well as IntX, it implements fast multiplication algorithm using FFT; it's also worth noticing that division for huge integers works few times faster in GMP comparing to IntX. GMP also has support for big floating-point numbers as well as for many numeric algorithms. For tests I was using <a href="http://www.codeplex.com/Download?ProjectName=IntX&DownloadId=102346">libgmp-3.dll</a> GMP 5.0.0 DLL built for Windows using MinGW; I also want to add that my performance comparing was primitive and its results are very approximate.<br /><br />So if you need to perform a lot of operations with big integers and must get the fastest possible speed from them then I'd suggest you using <a href="http://gmplib.org/" class="externalLink">GMP<span class="externalLinkIcon"></span></a> (distributed under LGPL license); if you work in Windows you can build it with Cygwin/MinGW or use some GMP Windows-friendly port like <a href="http://www.mpir.org/" class="externalLink">MPIR<span class="externalLinkIcon"></span></a>. However, if 8x speed loss on some operations is okay for your project and/or you don't want to include unmanaged code into your application then IntX should be enough for you.<br /><br />Btw, using GMP from C# is quite easy because there are GMP C#-wrappers available <a href="http://www.emilstefanov.net/Projects/GnuMpDotNet/" class="externalLink">here<span class="externalLinkIcon"></span></a> (this one I was using for tests) and <a href="http://gnumpnet.codeplex.com/" class="externalLink">there<span class="externalLinkIcon"></span></a>. But be careful with them - both wrappers I saw are releasing unmanaged resource they are referring (which is memory) only in Finalize() method override and not implementing IDisposable so you can end with unexpected OutOfMemoryException as I did.</div><div class="ClearBoth"></div>OysterFri, 30 Dec 2011 09:37:04 GMTUpdated Wiki: Home 20111230093704AUpdated Wiki: Homehttp://intx.codeplex.com/wikipage?version=34<div class="wikidoc"><h2><a href="http://nuget.org/packages/IntX" class="externalLink">Download IntX 1.0.0.0 from NuGet<span class="externalLinkIcon"></span></a></h2>
<b>Project Description</b><br />IntX is an arbitrary precision integers library written in pure C# 2.0 with fast - about O(N * log N) - multiplication/division algorithms implementation. It provides all the basic arithmetic operations on integers, comparing, bitwise shifting etc. It also allows parsing numbers in different bases and converting them to string, also in any base. The advantage of this library is fast multiplication, division and from base/to base conversion algorithms - all the fast versions of the algorithms are based on fast multiplication of big integers using Fast Hartley Transform which runs for O(N * log N * log log N) time instead of classic O(N^2).<br /><br />Project sources are now <a href="https://github.com/devoyster/IntXLib" class="externalLink">hosted on GitHub<span class="externalLinkIcon"></span></a>.<br /><br /><b>Bits of History</b><br />I have written IntX basically because I like big numbers and had some free time. Initial implementation was standard - I was using standard big integers +, -, *, / algorithms from Khuth book. After library was written I've decided to participate in contest held by <a href="http://gotdotnet.ru/" class="externalLink">GotDotNet.ru<span class="externalLinkIcon"></span></a> and received some replies which were saying that my library is too ... usual. Well, it was true, so I've decided to implement some more interesting algorithms in it.<br /><br />I've started with writing multiplication using <a href="http://en.wikipedia.org/wiki/Discrete_Hartley_transform" class="externalLink">Fast Hartley Transform<span class="externalLinkIcon"></span></a> so big integers multiplication time estimate became to be O(N * log N * log log N) (here N is amount of DWORDs in number representation) which was a bit better then O(N^2) with classic algorithm :) Then I saw fast algorithm for transforming from one base to another in Knuth book; it was based on fast multiplication so Parse()/ToString() started working faster - O(N * (log N)^2) instead of O(N^2). Finally division was also optimized (again, with the help of fast multiplication) - became as fast as multiplication.<br /><br />All this happened in 2005 year and in 2008 I've decided to publish this library on CodePlex - maybe it will be useful for someone out there (well, there is not so many similar libraries under .NET; also System.Numeric.BigInteger from .NET FW 3.5 was cancelled). Before publishing it on CodePlex I also made some cosmetic changes in code - used new .NET 2.0 features like generics (to minimize code duplication) and rewritten unit tests to use NUnit (they were previously written for MbUnit which is almost unknown and not used by community).<br /><br /><b>Code Example</b><br />Here is the sample of code which uses IntX and calculates 42 in power 1048576 (which is 2^20):<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">using</span> System;
<span style="color:Blue;">using</span> System.Diagnostics;
<span style="color:Blue;">using</span> Oyster.Math;
<span style="color:Blue;">namespace</span> IntxTestApp
{
<span style="color:Blue;">class</span> Program
{
<span style="color:Blue;">static</span> <span style="color:Blue;">void</span> Calc()
{
Stopwatch sw = Stopwatch.StartNew();
IntX.Pow(42, 1 << 20);
sw.Stop();
Console.WriteLine(<span style="color:#A31515;">"{0} ms"</span>, sw.ElapsedMilliseconds);
}
<span style="color:Blue;">static</span> <span style="color:Blue;">void</span> Main()
{
Calc();
IntX.GlobalSettings.MultiplyMode = MultiplyMode.Classic;
Calc();
}
}
}
</pre></div>First Calc() call uses fast multiplication implementation (which is default), second - classic one. On my machine (Win XP Pro SP2, P4 2.8 GHz, 2 GB RAM) first call is <b>70 times</b> faster than the second one (1 second against 68 seconds). Resulting number has 1,702,101 digits; you can get it here: <a href="http://www.codeplex.com/Download?ProjectName=IntX&DownloadId=27428">42pow1048576.txt</a>.<br /><br />Another example is factorial calculation:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">using</span> System;
<span style="color:Blue;">using</span> Oyster.Math;
<span style="color:Blue;">namespace</span> IntxTestApp
{
<span style="color:Blue;">class</span> Program
{
<span style="color:Blue;">static</span> IntX Factorial(IntX n)
{
<span style="color:Blue;">if</span> (n < 0)
{
<span style="color:Blue;">throw</span> <span style="color:Blue;">new</span> ArgumentException(<span style="color:#A31515;">"Can't calculate factorial for negative number."</span>, <span style="color:#A31515;">"n"</span>);
}
<span style="color:Blue;">return</span> n == 0 ? 1 : n * Factorial(n - 1);
}
<span style="color:Blue;">static</span> <span style="color:Blue;">void</span> Main()
{
Console.WriteLine(Factorial(10000));
}
}
}
</pre></div>As you can see, IntX implements all the standard arithmetic operators so its usage is transparent for developer - like if you're working with usual integer.<br /><br /><b>FHT and Calculations Precision</b><br />Internally IntX library operates with floating-point numbers when multiplication using FHT is performed so at some point it stops working correctly and loses precision. Luckily, this unpleasant side-effects effects are starting to appear when integer size is about 2^28 bytes i.e. for really huge integers. Anyway, to catch such errors I have added FHT multiplication result validity check into code - it takes N last digits of each big integer, multiplies them using classic approach and then compares last N digits of classic result with last N digits of FHT result (so it's kind of simplified CRC check). If any inconsistency is found then FhtMultiplicationException is thrown; this check can be disabled using global settings.<br /><br /><b>Internal Representation and ToString() Performance</b><br />For a really huge integer numbers (like 42 in power 1048576 above) ToString() call can take a very long time to execute. This is because internally IntX big integer is stored as 2^32-base number in uint[] array and to generate decimal string output it should be converted from 2^32 base to decimal base. Such digits storage approach was chosen intentionally - it makes ToString() slower but uses memory efficiently and makes primitive operations on digits faster than power of 10-base storage (which would make ToString() working faster) and I think that usually computations are used more often than ToString().<br /><br /><b>Future Plans</b><br />I have no plans to further develop this library - I'm just sharing it with the community.<br /><br /><b>System.Numerics.BigInteger in .NET 4.0</b><br />According to the <a href="http://blogs.msdn.com/bclteam/archive/2008/11/04/what-s-new-in-the-bcl-in-net-4-0-justin-van-patten.aspx" class="externalLink">BCL team blog<span class="externalLinkIcon"></span></a> MS is going to introduce System.Numerics.BigInteger class in .NET 4.0, this time for sure :) Once I saw this blog entity I was interested in performance of their solution - you can download preliminary version together with <a href="http://code.msdn.microsoft.com/solverfoundation" class="externalLink">MS Solver Foundation<span class="externalLinkIcon"></span></a> (it's for .NET 3.5), it's called Microsoft.SolverFoundation.Common.BigInteger in there. I did some tests and it appears that BigInteger has performance in general comparable with IntX on standard operations but starts losing when FHT comes into play (when multiplying really big integers, for example).<br /><br />So internally System.Numerics.BigInteger seems to use standard arbitrary arithmetic algorithms and I am not worrying about IntX library since, due to its use of FHT, it can be times faster for really big integers.<br /><br /><b>Comparing IntX Performance to GMP</b><br />While IntX library is fast among other libraries written for .NET it can't really compete with <a href="http://gmplib.org/" class="externalLink">The GNU MP Library<span class="externalLinkIcon"></span></a> - one of the fastest well-known Bignum libraries in the world. GNU MP (or GMP) is written in plain C and Assembly language so it compiles into optimized native code, it also uses fast calculation algorithms - that's why it's very fast. I have compared IntX performance to GMP on basic arithmetic operations and it appeared that GMP is up to 8 times faster than IntX on certain operations. Actually for me it is a good result - IntX written in managed code is still quite fast :) GMP also has comparable performance on huge integers multiplication since, as well as IntX, it implements fast multiplication algorithm using FFT; it's also worth noticing that division for huge integers works few times faster in GMP comparing to IntX. GMP also has support for big floating-point numbers as well as for many numeric algorithms. For tests I was using <a href="http://www.codeplex.com/Download?ProjectName=IntX&DownloadId=102346">libgmp-3.dll</a> GMP 5.0.0 DLL built for Windows using MinGW; I also want to add that my performance comparing was primitive and its results are very approximate.<br /><br />So if you need to perform a lot of operations with big integers and must get the fastest possible speed from them then I'd suggest you using <a href="http://gmplib.org/" class="externalLink">GMP<span class="externalLinkIcon"></span></a> (distributed under LGPL license); if you work in Windows you can build it with Cygwin/MinGW or use some GMP Windows-friendly port like <a href="http://www.mpir.org/" class="externalLink">MPIR<span class="externalLinkIcon"></span></a>. However, if 8x speed loss on some operations is okay for your project and/or you don't want to include unmanaged code into your application then IntX should be enough for you.<br /><br />Btw, using GMP from C# is quite easy because there are GMP C#-wrappers available <a href="http://www.emilstefanov.net/Projects/GnuMpDotNet/" class="externalLink">here<span class="externalLinkIcon"></span></a> (this one I was using for tests) and <a href="http://gnumpnet.codeplex.com/" class="externalLink">there<span class="externalLinkIcon"></span></a>. But be careful with them - both wrappers I saw are releasing unmanaged resource they are referring (which is memory) only in Finalize() method override and not implementing IDisposable so you can end with unexpected OutOfMemoryException as I did.</div><div class="ClearBoth"></div>OysterTue, 27 Dec 2011 21:06:32 GMTUpdated Wiki: Home 20111227090632PUpdated Wiki: Homehttp://intx.codeplex.com/wikipage?version=33<div class="wikidoc"><h2><a href="http://nuget.org/packages/IntX" class="externalLink">Download from NuGet<span class="externalLinkIcon"></span></a></h2>
<b>Project Description</b><br />IntX is an arbitrary precision integers library written in pure C# 2.0 with fast - about O(N * log N) - multiplication/division algorithms implementation. It provides all the basic arithmetic operations on integers, comparing, bitwise shifting etc. It also allows parsing numbers in different bases and converting them to string, also in any base. The advantage of this library is fast multiplication, division and from base/to base conversion algorithms - all the fast versions of the algorithms are based on fast multiplication of big integers using Fast Hartley Transform which runs for O(N * log N * log log N) time instead of classic O(N^2).<br /><br />Project sources are now <a href="https://github.com/devoyster/IntXLib" class="externalLink">hosted on GitHub<span class="externalLinkIcon"></span></a>.<br /><br /><b>Bits of History</b><br />I have written IntX basically because I like big numbers and had some free time. Initial implementation was standard - I was using standard big integers +, -, *, / algorithms from Khuth book. After library was written I've decided to participate in contest held by <a href="http://gotdotnet.ru/" class="externalLink">GotDotNet.ru<span class="externalLinkIcon"></span></a> and received some replies which were saying that my library is too ... usual. Well, it was true, so I've decided to implement some more interesting algorithms in it.<br /><br />I've started with writing multiplication using <a href="http://en.wikipedia.org/wiki/Discrete_Hartley_transform" class="externalLink">Fast Hartley Transform<span class="externalLinkIcon"></span></a> so big integers multiplication time estimate became to be O(N * log N * log log N) (here N is amount of DWORDs in number representation) which was a bit better then O(N^2) with classic algorithm :) Then I saw fast algorithm for transforming from one base to another in Knuth book; it was based on fast multiplication so Parse()/ToString() started working faster - O(N * (log N)^2) instead of O(N^2). Finally division was also optimized (again, with the help of fast multiplication) - became as fast as multiplication.<br /><br />All this happened in 2005 year and in 2008 I've decided to publish this library on CodePlex - maybe it will be useful for someone out there (well, there is not so many similar libraries under .NET; also System.Numeric.BigInteger from .NET FW 3.5 was cancelled). Before publishing it on CodePlex I also made some cosmetic changes in code - used new .NET 2.0 features like generics (to minimize code duplication) and rewritten unit tests to use NUnit (they were previously written for MbUnit which is almost unknown and not used by community).<br /><br /><b>Code Example</b><br />Here is the sample of code which uses IntX and calculates 42 in power 1048576 (which is 2^20):<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">using</span> System;
<span style="color:Blue;">using</span> System.Diagnostics;
<span style="color:Blue;">using</span> Oyster.Math;
<span style="color:Blue;">namespace</span> IntxTestApp
{
<span style="color:Blue;">class</span> Program
{
<span style="color:Blue;">static</span> <span style="color:Blue;">void</span> Calc()
{
Stopwatch sw = Stopwatch.StartNew();
IntX.Pow(42, 1 << 20);
sw.Stop();
Console.WriteLine(<span style="color:#A31515;">"{0} ms"</span>, sw.ElapsedMilliseconds);
}
<span style="color:Blue;">static</span> <span style="color:Blue;">void</span> Main()
{
Calc();
IntX.GlobalSettings.MultiplyMode = MultiplyMode.Classic;
Calc();
}
}
}
</pre></div>First Calc() call uses fast multiplication implementation (which is default), second - classic one. On my machine (Win XP Pro SP2, P4 2.8 GHz, 2 GB RAM) first call is <b>70 times</b> faster than the second one (1 second against 68 seconds). Resulting number has 1,702,101 digits; you can get it here: <a href="http://www.codeplex.com/Download?ProjectName=IntX&DownloadId=27428">42pow1048576.txt</a>.<br /><br />Another example is factorial calculation:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">using</span> System;
<span style="color:Blue;">using</span> Oyster.Math;
<span style="color:Blue;">namespace</span> IntxTestApp
{
<span style="color:Blue;">class</span> Program
{
<span style="color:Blue;">static</span> IntX Factorial(IntX n)
{
<span style="color:Blue;">if</span> (n < 0)
{
<span style="color:Blue;">throw</span> <span style="color:Blue;">new</span> ArgumentException(<span style="color:#A31515;">"Can't calculate factorial for negative number."</span>, <span style="color:#A31515;">"n"</span>);
}
<span style="color:Blue;">return</span> n == 0 ? 1 : n * Factorial(n - 1);
}
<span style="color:Blue;">static</span> <span style="color:Blue;">void</span> Main()
{
Console.WriteLine(Factorial(10000));
}
}
}
</pre></div>As you can see, IntX implements all the standard arithmetic operators so its usage is transparent for developer - like if you're working with usual integer.<br /><br /><b>FHT and Calculations Precision</b><br />Internally IntX library operates with floating-point numbers when multiplication using FHT is performed so at some point it stops working correctly and loses precision. Luckily, this unpleasant side-effects effects are starting to appear when integer size is about 2^28 bytes i.e. for really huge integers. Anyway, to catch such errors I have added FHT multiplication result validity check into code - it takes N last digits of each big integer, multiplies them using classic approach and then compares last N digits of classic result with last N digits of FHT result (so it's kind of simplified CRC check). If any inconsistency is found then FhtMultiplicationException is thrown; this check can be disabled using global settings.<br /><br /><b>Internal Representation and ToString() Performance</b><br />For a really huge integer numbers (like 42 in power 1048576 above) ToString() call can take a very long time to execute. This is because internally IntX big integer is stored as 2^32-base number in uint[] array and to generate decimal string output it should be converted from 2^32 base to decimal base. Such digits storage approach was chosen intentionally - it makes ToString() slower but uses memory efficiently and makes primitive operations on digits faster than power of 10-base storage (which would make ToString() working faster) and I think that usually computations are used more often than ToString().<br /><br /><b>Future Plans</b><br />I have no plans to further develop this library - I'm just sharing it with the community.<br /><br /><b>System.Numerics.BigInteger in .NET 4.0</b><br />According to the <a href="http://blogs.msdn.com/bclteam/archive/2008/11/04/what-s-new-in-the-bcl-in-net-4-0-justin-van-patten.aspx" class="externalLink">BCL team blog<span class="externalLinkIcon"></span></a> MS is going to introduce System.Numerics.BigInteger class in .NET 4.0, this time for sure :) Once I saw this blog entity I was interested in performance of their solution - you can download preliminary version together with <a href="http://code.msdn.microsoft.com/solverfoundation" class="externalLink">MS Solver Foundation<span class="externalLinkIcon"></span></a> (it's for .NET 3.5), it's called Microsoft.SolverFoundation.Common.BigInteger in there. I did some tests and it appears that BigInteger has performance in general comparable with IntX on standard operations but starts losing when FHT comes into play (when multiplying really big integers, for example).<br /><br />So internally System.Numerics.BigInteger seems to use standard arbitrary arithmetic algorithms and I am not worrying about IntX library since, due to its use of FHT, it can be times faster for really big integers.<br /><br /><b>Comparing IntX Performance to GMP</b><br />While IntX library is fast among other libraries written for .NET it can't really compete with <a href="http://gmplib.org/" class="externalLink">The GNU MP Library<span class="externalLinkIcon"></span></a> - one of the fastest well-known Bignum libraries in the world. GNU MP (or GMP) is written in plain C and Assembly language so it compiles into optimized native code, it also uses fast calculation algorithms - that's why it's very fast. I have compared IntX performance to GMP on basic arithmetic operations and it appeared that GMP is up to 8 times faster than IntX on certain operations. Actually for me it is a good result - IntX written in managed code is still quite fast :) GMP also has comparable performance on huge integers multiplication since, as well as IntX, it implements fast multiplication algorithm using FFT; it's also worth noticing that division for huge integers works few times faster in GMP comparing to IntX. GMP also has support for big floating-point numbers as well as for many numeric algorithms. For tests I was using <a href="http://www.codeplex.com/Download?ProjectName=IntX&DownloadId=102346">libgmp-3.dll</a> GMP 5.0.0 DLL built for Windows using MinGW; I also want to add that my performance comparing was primitive and its results are very approximate.<br /><br />So if you need to perform a lot of operations with big integers and must get the fastest possible speed from them then I'd suggest you using <a href="http://gmplib.org/" class="externalLink">GMP<span class="externalLinkIcon"></span></a> (distributed under LGPL license); if you work in Windows you can build it with Cygwin/MinGW or use some GMP Windows-friendly port like <a href="http://www.mpir.org/" class="externalLink">MPIR<span class="externalLinkIcon"></span></a>. However, if 8x speed loss on some operations is okay for your project and/or you don't want to include unmanaged code into your application then IntX should be enough for you.<br /><br />Btw, using GMP from C# is quite easy because there are GMP C#-wrappers available <a href="http://www.emilstefanov.net/Projects/GnuMpDotNet/" class="externalLink">here<span class="externalLinkIcon"></span></a> (this one I was using for tests) and <a href="http://gnumpnet.codeplex.com/" class="externalLink">there<span class="externalLinkIcon"></span></a>. But be careful with them - both wrappers I saw are releasing unmanaged resource they are referring (which is memory) only in Finalize() method override and not implementing IDisposable so you can end with unexpected OutOfMemoryException as I did.</div><div class="ClearBoth"></div>OysterTue, 27 Dec 2011 20:57:58 GMTUpdated Wiki: Home 20111227085758PUpdated Wiki: Homehttp://intx.codeplex.com/wikipage?version=32<div class="wikidoc"><b>Project Description</b><br />IntX is an arbitrary precision integers library written in pure C# 2.0 with fast - about O(N * log N) - multiplication/division algorithms implementation. It provides all the basic arithmetic operations on integers, comparing, bitwise shifting etc. It also allows parsing numbers in different bases and converting them to string, also in any base. The advantage of this library is fast multiplication, division and from base/to base conversion algorithms - all the fast versions of the algorithms are based on fast multiplication of big integers using Fast Hartley Transform which runs for O(N * log N * log log N) time instead of classic O(N^2).<br /><br />Project sources are now <a href="https://github.com/devoyster/IntXLib" class="externalLink">hosted on GitHub<span class="externalLinkIcon"></span></a> and binaries are <a href="http://nuget.org/packages/IntX" class="externalLink">distributed via NuGet<span class="externalLinkIcon"></span></a>.<br /><br /><b>Bits of History</b><br />I have written IntX basically because I like big numbers and had some free time. Initial implementation was standard - I was using standard big integers +, -, *, / algorithms from Khuth book. After library was written I've decided to participate in contest held by <a href="http://gotdotnet.ru/" class="externalLink">GotDotNet.ru<span class="externalLinkIcon"></span></a> and received some replies which were saying that my library is too ... usual. Well, it was true, so I've decided to implement some more interesting algorithms in it.<br /><br />I've started with writing multiplication using <a href="http://en.wikipedia.org/wiki/Discrete_Hartley_transform" class="externalLink">Fast Hartley Transform<span class="externalLinkIcon"></span></a> so big integers multiplication time estimate became to be O(N * log N * log log N) (here N is amount of DWORDs in number representation) which was a bit better then O(N^2) with classic algorithm :) Then I saw fast algorithm for transforming from one base to another in Knuth book; it was based on fast multiplication so Parse()/ToString() started working faster - O(N * (log N)^2) instead of O(N^2). Finally division was also optimized (again, with the help of fast multiplication) - became as fast as multiplication.<br /><br />All this happened in 2005 year and in 2008 I've decided to publish this library on CodePlex - maybe it will be useful for someone out there (well, there is not so many similar libraries under .NET; also System.Numeric.BigInteger from .NET FW 3.5 was cancelled). Before publishing it on CodePlex I also made some cosmetic changes in code - used new .NET 2.0 features like generics (to minimize code duplication) and rewritten unit tests to use NUnit (they were previously written for MbUnit which is almost unknown and not used by community).<br /><br /><b>Code Example</b><br />Here is the sample of code which uses IntX and calculates 42 in power 1048576 (which is 2^20):<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">using</span> System;
<span style="color:Blue;">using</span> System.Diagnostics;
<span style="color:Blue;">using</span> Oyster.Math;
<span style="color:Blue;">namespace</span> IntxTestApp
{
<span style="color:Blue;">class</span> Program
{
<span style="color:Blue;">static</span> <span style="color:Blue;">void</span> Calc()
{
Stopwatch sw = Stopwatch.StartNew();
IntX.Pow(42, 1 << 20);
sw.Stop();
Console.WriteLine(<span style="color:#A31515;">"{0} ms"</span>, sw.ElapsedMilliseconds);
}
<span style="color:Blue;">static</span> <span style="color:Blue;">void</span> Main()
{
Calc();
IntX.GlobalSettings.MultiplyMode = MultiplyMode.Classic;
Calc();
}
}
}
</pre></div>First Calc() call uses fast multiplication implementation (which is default), second - classic one. On my machine (Win XP Pro SP2, P4 2.8 GHz, 2 GB RAM) first call is <b>70 times</b> faster than the second one (1 second against 68 seconds). Resulting number has 1,702,101 digits; you can get it here: <a href="http://www.codeplex.com/Download?ProjectName=IntX&DownloadId=27428">42pow1048576.txt</a>.<br /><br />Another example is factorial calculation:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">using</span> System;
<span style="color:Blue;">using</span> Oyster.Math;
<span style="color:Blue;">namespace</span> IntxTestApp
{
<span style="color:Blue;">class</span> Program
{
<span style="color:Blue;">static</span> IntX Factorial(IntX n)
{
<span style="color:Blue;">if</span> (n < 0)
{
<span style="color:Blue;">throw</span> <span style="color:Blue;">new</span> ArgumentException(<span style="color:#A31515;">"Can't calculate factorial for negative number."</span>, <span style="color:#A31515;">"n"</span>);
}
<span style="color:Blue;">return</span> n == 0 ? 1 : n * Factorial(n - 1);
}
<span style="color:Blue;">static</span> <span style="color:Blue;">void</span> Main()
{
Console.WriteLine(Factorial(10000));
}
}
}
</pre></div>As you can see, IntX implements all the standard arithmetic operators so its usage is transparent for developer - like if you're working with usual integer.<br /><br /><b>FHT and Calculations Precision</b><br />Internally IntX library operates with floating-point numbers when multiplication using FHT is performed so at some point it stops working correctly and loses precision. Luckily, this unpleasant side-effects effects are starting to appear when integer size is about 2^28 bytes i.e. for really huge integers. Anyway, to catch such errors I have added FHT multiplication result validity check into code - it takes N last digits of each big integer, multiplies them using classic approach and then compares last N digits of classic result with last N digits of FHT result (so it's kind of simplified CRC check). If any inconsistency is found then FhtMultiplicationException is thrown; this check can be disabled using global settings.<br /><br /><b>Internal Representation and ToString() Performance</b><br />For a really huge integer numbers (like 42 in power 1048576 above) ToString() call can take a very long time to execute. This is because internally IntX big integer is stored as 2^32-base number in uint[] array and to generate decimal string output it should be converted from 2^32 base to decimal base. Such digits storage approach was chosen intentionally - it makes ToString() slower but uses memory efficiently and makes primitive operations on digits faster than power of 10-base storage (which would make ToString() working faster) and I think that usually computations are used more often than ToString().<br /><br /><b>Future Plans</b><br />I have no plans to further develop this library - I'm just sharing it with the community.<br /><br /><b>System.Numerics.BigInteger in .NET 4.0</b><br />According to the <a href="http://blogs.msdn.com/bclteam/archive/2008/11/04/what-s-new-in-the-bcl-in-net-4-0-justin-van-patten.aspx" class="externalLink">BCL team blog<span class="externalLinkIcon"></span></a> MS is going to introduce System.Numerics.BigInteger class in .NET 4.0, this time for sure :) Once I saw this blog entity I was interested in performance of their solution - you can download preliminary version together with <a href="http://code.msdn.microsoft.com/solverfoundation" class="externalLink">MS Solver Foundation<span class="externalLinkIcon"></span></a> (it's for .NET 3.5), it's called Microsoft.SolverFoundation.Common.BigInteger in there. I did some tests and it appears that BigInteger has performance in general comparable with IntX on standard operations but starts losing when FHT comes into play (when multiplying really big integers, for example).<br /><br />So internally System.Numerics.BigInteger seems to use standard arbitrary arithmetic algorithms and I am not worrying about IntX library since, due to its use of FHT, it can be times faster for really big integers.<br /><br /><b>Comparing IntX Performance to GMP</b><br />While IntX library is fast among other libraries written for .NET it can't really compete with <a href="http://gmplib.org/" class="externalLink">The GNU MP Library<span class="externalLinkIcon"></span></a> - one of the fastest well-known Bignum libraries in the world. GNU MP (or GMP) is written in plain C and Assembly language so it compiles into optimized native code, it also uses fast calculation algorithms - that's why it's very fast. I have compared IntX performance to GMP on basic arithmetic operations and it appeared that GMP is up to 8 times faster than IntX on certain operations. Actually for me it is a good result - IntX written in managed code is still quite fast :) GMP also has comparable performance on huge integers multiplication since, as well as IntX, it implements fast multiplication algorithm using FFT; it's also worth noticing that division for huge integers works few times faster in GMP comparing to IntX. GMP also has support for big floating-point numbers as well as for many numeric algorithms. For tests I was using <a href="http://www.codeplex.com/Download?ProjectName=IntX&DownloadId=102346">libgmp-3.dll</a> GMP 5.0.0 DLL built for Windows using MinGW; I also want to add that my performance comparing was primitive and its results are very approximate.<br /><br />So if you need to perform a lot of operations with big integers and must get the fastest possible speed from them then I'd suggest you using <a href="http://gmplib.org/" class="externalLink">GMP<span class="externalLinkIcon"></span></a> (distributed under LGPL license); if you work in Windows you can build it with Cygwin/MinGW or use some GMP Windows-friendly port like <a href="http://www.mpir.org/" class="externalLink">MPIR<span class="externalLinkIcon"></span></a>. However, if 8x speed loss on some operations is okay for your project and/or you don't want to include unmanaged code into your application then IntX should be enough for you.<br /><br />Btw, using GMP from C# is quite easy because there are GMP C#-wrappers available <a href="http://www.emilstefanov.net/Projects/GnuMpDotNet/" class="externalLink">here<span class="externalLinkIcon"></span></a> (this one I was using for tests) and <a href="http://gnumpnet.codeplex.com/" class="externalLink">there<span class="externalLinkIcon"></span></a>. But be careful with them - both wrappers I saw are releasing unmanaged resource they are referring (which is memory) only in Finalize() method override and not implementing IDisposable so you can end with unexpected OutOfMemoryException as I did.</div><div class="ClearBoth"></div>OysterFri, 23 Dec 2011 12:30:23 GMTUpdated Wiki: Home 20111223123023PUpdated Wiki: Homehttp://intx.codeplex.com/wikipage?version=31<div class="wikidoc"><b>Project Description</b><br />IntX is an arbitrary precision integers library written in pure C# 2.0 with fast - about O(N * log N) - multiplication/division algorithms implementation. It provides all the basic arithmetic operations on integers, comparing, bitwise shifting etc. It also allows parsing numbers in different bases and converting them to string, also in any base. The advantage of this library is fast multiplication, division and from base/to base conversion algorithms - all the fast versions of the algorithms are based on fast multiplication of big integers using Fast Hartley Transform which runs for O(N * log N * log log N) time instead of classic O(N^2).<br /><br /><b>Bits of History</b><br />I have written IntX basically because I like big numbers and had some free time. Initial implementation was standard - I was using standard big integers +, -, *, / algorithms from Khuth book. After library was written I've decided to participate in contest held by <a href="http://gotdotnet.ru/" class="externalLink">GotDotNet.ru<span class="externalLinkIcon"></span></a> and received some replies which were saying that my library is too ... usual. Well, it was true, so I've decided to implement some more interesting algorithms in it.<br /><br />I've started with writing multiplication using <a href="http://en.wikipedia.org/wiki/Discrete_Hartley_transform" class="externalLink">Fast Hartley Transform<span class="externalLinkIcon"></span></a> so big integers multiplication time estimate became to be O(N * log N * log log N) (here N is amount of DWORDs in number representation) which was a bit better then O(N^2) with classic algorithm :) Then I saw fast algorithm for transforming from one base to another in Knuth book; it was based on fast multiplication so Parse()/ToString() started working faster - O(N * (log N)^2) instead of O(N^2). Finally division was also optimized (again, with the help of fast multiplication) - became as fast as multiplication.<br /><br />All this happened in 2005 year and in 2008 I've decided to publish this library on CodePlex - maybe it will be useful for someone out there (well, there is not so many similar libraries under .NET; also System.Numeric.BigInteger from .NET FW 3.5 was cancelled). Before publishing it on CodePlex I also made some cosmetic changes in code - used new .NET 2.0 features like generics (to minimize code duplication) and rewritten unit tests to use NUnit (they were previously written for MbUnit which is almost unknown and not used by community).<br /><br /><b>Code Example</b><br />Here is the sample of code which uses IntX and calculates 42 in power 1048576 (which is 2^20):<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">using</span> System;
<span style="color:Blue;">using</span> System.Diagnostics;
<span style="color:Blue;">using</span> Oyster.Math;
<span style="color:Blue;">namespace</span> IntxTestApp
{
<span style="color:Blue;">class</span> Program
{
<span style="color:Blue;">static</span> <span style="color:Blue;">void</span> Calc()
{
Stopwatch sw = Stopwatch.StartNew();
IntX.Pow(42, 1 << 20);
sw.Stop();
Console.WriteLine(<span style="color:#A31515;">"{0} ms"</span>, sw.ElapsedMilliseconds);
}
<span style="color:Blue;">static</span> <span style="color:Blue;">void</span> Main()
{
Calc();
IntX.GlobalSettings.MultiplyMode = MultiplyMode.Classic;
Calc();
}
}
}
</pre></div>First Calc() call uses fast multiplication implementation (which is default), second - classic one. On my machine (Win XP Pro SP2, P4 2.8 GHz, 2 GB RAM) first call is <b>70 times</b> faster than the second one (1 second against 68 seconds). Resulting number has 1,702,101 digits; you can get it here: <a href="javascript:window.location.href='http://intx.codeplex.com/Project/Download/FileDownload.aspx?DownloadId=27428';">42pow1048576.txt</a>.<br /><br />Another example is factorial calculation:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">using</span> System;
<span style="color:Blue;">using</span> Oyster.Math;
<span style="color:Blue;">namespace</span> IntxTestApp
{
<span style="color:Blue;">class</span> Program
{
<span style="color:Blue;">static</span> IntX Factorial(IntX n)
{
<span style="color:Blue;">if</span> (n < 0)
{
<span style="color:Blue;">throw</span> <span style="color:Blue;">new</span> ArgumentException(<span style="color:#A31515;">"Can't calculate factorial for negative number."</span>, <span style="color:#A31515;">"n"</span>);
}
<span style="color:Blue;">return</span> n == 0 ? 1 : n * Factorial(n - 1);
}
<span style="color:Blue;">static</span> <span style="color:Blue;">void</span> Main()
{
Console.WriteLine(Factorial(10000));
}
}
}
</pre></div>As you can see, IntX implements all the standard arithmetic operators so its usage is transparent for developer - like if you're working with usual integer.<br /><br /><b>FHT and Calculations Precision</b><br />Internally IntX library operates with floating-point numbers when multiplication using FHT is performed so at some point it stops working correctly and loses precision. Luckily, this unpleasant side-effects effects are starting to appear when integer size is about 2^28 bytes i.e. for really huge integers. Anyway, to catch such errors I have added FHT multiplication result validity check into code - it takes N last digits of each big integer, multiplies them using classic approach and then compares last N digits of classic result with last N digits of FHT result (so it's kind of simplified CRC check). If any inconsistency is found then FhtMultiplicationException is thrown; this check can be disabled using global settings.<br /><br /><b>Internal Representation and ToString() Performance</b><br />For a really huge integer numbers (like 42 in power 1048576 above) ToString() call can take a very long time to execute. This is because internally IntX big integer is stored as 2^32-base number in uint[] array and to generate decimal string output it should be converted from 2^32 base to decimal base. Such digits storage approach was chosen intentionally - it makes ToString() slower but uses memory efficiently and makes primitive operations on digits faster than power of 10-base storage (which would make ToString() working faster) and I think that usually computations are used more often than ToString().<br /><br /><b>Future Plans</b><br />I have no plans to further develop this library - I'm just sharing it with the community.<br /><br /><b>System.Numerics.BigInteger in .NET 4.0</b><br />According to the <a href="http://blogs.msdn.com/bclteam/archive/2008/11/04/what-s-new-in-the-bcl-in-net-4-0-justin-van-patten.aspx" class="externalLink">BCL team blog<span class="externalLinkIcon"></span></a> MS is going to introduce System.Numerics.BigInteger class in .NET 4.0, this time for sure :) Once I saw this blog entity I was interested in performance of their solution - you can download preliminary version together with <a href="http://code.msdn.microsoft.com/solverfoundation" class="externalLink">MS Solver Foundation<span class="externalLinkIcon"></span></a> (it's for .NET 3.5), it's called Microsoft.SolverFoundation.Common.BigInteger in there. I did some tests and it appears that BigInteger has performance in general comparable with IntX on standard operations but starts losing when FHT comes into play (when multiplying really big integers, for example).<br /><br />So internally System.Numerics.BigInteger seems to use standard arbitrary arithmetic algorithms and I am not worrying about IntX library since, due to its use of FHT, it can be times faster for really big integers.<br /><br /><b>Comparing IntX Performance to GMP</b><br />While IntX library is fast among other libraries written for .NET it can't really compete with <a href="http://gmplib.org/" class="externalLink">The GNU MP Library<span class="externalLinkIcon"></span></a> - one of the fastest well-known Bignum libraries in the world. GNU MP (or GMP) is written in plain C and Assembly language so it compiles into optimized native code, it also uses fast calculation algorithms - that's why it's very fast. I have compared IntX performance to GMP on basic arithmetic operations and it appeared that GMP is up to 8 times faster than IntX on certain operations. Actually for me it is a good result - IntX written in managed code is still quite fast :) GMP also has comparable performance on huge integers multiplication since, as well as IntX, it implements fast multiplication algorithm using FFT; it's also worth noticing that division for huge integers works few times faster in GMP comparing to IntX. GMP also has support for big floating-point numbers as well as for many numeric algorithms. For tests I was using <a href="javascript:window.location.href='http://intx.codeplex.com/Project/Download/FileDownload.aspx?DownloadId=102346';">libgmp-3.dll</a> GMP 5.0.0 DLL built for Windows using MinGW; I also want to add that my performance comparing was primitive and its results are very approximate.<br /><br />So if you need to perform a lot of operations with big integers and must get the fastest possible speed from them then I'd suggest you using <a href="http://gmplib.org/" class="externalLink">GMP<span class="externalLinkIcon"></span></a> (distributed under LGPL license); if you work in Windows you can build it with Cygwin/MinGW or use some GMP Windows-friendly port like <a href="http://www.mpir.org/" class="externalLink">MPIR<span class="externalLinkIcon"></span></a>. However, if 8x speed loss on some operations is okay for your project and/or you don't want to include unmanaged code into your application then IntX should be enough for you.<br /><br />Btw, using GMP from C# is quite easy because there are GMP C#-wrappers available <a href="http://www.emilstefanov.net/Projects/GnuMpDotNet/" class="externalLink">here<span class="externalLinkIcon"></span></a> (this one I was using for tests) and <a href="http://gnumpnet.codeplex.com/" class="externalLink">there<span class="externalLinkIcon"></span></a>. But be careful with them - both wrappers I saw are releasing unmanaged resource they are referring (which is memory) only in Finalize() method override and not implementing IDisposable so you can end with unexpected OutOfMemoryException as I did.</div><div class="ClearBoth"></div>OysterTue, 11 May 2010 14:06:30 GMTUpdated Wiki: Home 20100511020630PUpdated Wiki: Homehttp://intx.codeplex.com/wikipage?version=30<div class="wikidoc"><b>Project Description</b><br />IntX is an arbitrary precision integers library written in pure C# 2.0 with fast - about O(N * log N) - multiplication/division algorithms implementation. It provides all the basic arithmetic operations on integers, comparing, bitwise shifting etc. It also allows parsing numbers in different bases and converting them to string, also in any base. The advantage of this library is fast multiplication, division and from base/to base conversion algorithms - all the fast versions of the algorithms are based on fast multiplication of big integers using Fast Hartley Transform which runs for O(N * log N * log log N) time instead of classic O(N^2).<br /><br /><b>Bits of History</b><br />I have written IntX basically because I like big numbers and had some free time. Initial implementation was standard - I was using standard big integers +, -, *, / algorithms from Khuth book. After library was written I've decided to participate in contest held by <a href="http://gotdotnet.ru/" class="externalLink">GotDotNet.ru<span class="externalLinkIcon"></span></a> and received some replies which were saying that my library is too ... usual. Well, it was true, so I've decided to implement some more interesting algorithms in it.<br /><br />I've started with writing multiplication using <a href="http://en.wikipedia.org/wiki/Discrete_Hartley_transform" class="externalLink">Fast Hartley Transform<span class="externalLinkIcon"></span></a> so big integers multiplication time estimate became to be O(N * log N * log log N) (here N is amount of DWORDs in number representation) which was a bit better then O(N^2) with classic algorithm :) Then I saw fast algorithm for transforming from one base to another in Knuth book; it was based on fast multiplication so Parse()/ToString() started working faster - O(N * (log N)^2) instead of O(N^2). Finally division was also optimized (again, with the help of fast multiplication) - became as fast as multiplication.<br /><br />All this happened in 2005 year and in 2008 I've decided to publish this library on CodePlex - maybe it will be useful for someone out there (well, there is not so many similar libraries under .NET; also System.Numeric.BigInteger from .NET FW 3.5 was cancelled). Before publishing it on CodePlex I also made some cosmetic changes in code - used new .NET 2.0 features like generics (to minimize code duplication) and rewritten unit tests to use NUnit (they were previously written for MbUnit which is almost unknown and not used by community).<br /><br /><b>Code Example</b><br />Here is the sample of code which uses IntX and calculates 42 in power 1048576 (which is 2^20):<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">using</span> System;
<span style="color:Blue;">using</span> System.Diagnostics;
<span style="color:Blue;">using</span> Oyster.Math;
<span style="color:Blue;">namespace</span> IntxTestApp
{
<span style="color:Blue;">class</span> Program
{
<span style="color:Blue;">static</span> <span style="color:Blue;">void</span> Calc()
{
Stopwatch sw = Stopwatch.StartNew();
IntX.Pow(42, 1 << 20);
sw.Stop();
Console.WriteLine(<span style="color:#A31515;">"{0} ms"</span>, sw.ElapsedMilliseconds);
}
<span style="color:Blue;">static</span> <span style="color:Blue;">void</span> Main()
{
Calc();
IntX.GlobalSettings.MultiplyMode = MultiplyMode.Classic;
Calc();
}
}
}
</pre></div>First Calc() call uses fast multiplication implementation (which is default), second - classic one. On my machine (Win XP Pro SP2, P4 2.8 GHz, 2 GB RAM) first call is <b>70 times</b> faster than the second one (1 second against 68 seconds). Resulting number has 1,702,101 digits; you can get it here: <a href="javascript:window.location.href='http://intx.codeplex.com/Project/Download/FileDownload.aspx?DownloadId=27428';">42pow1048576.txt</a>.<br /><br />Another example is factorial calculation:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">using</span> System;
<span style="color:Blue;">using</span> Oyster.Math;
<span style="color:Blue;">namespace</span> IntxTestApp
{
<span style="color:Blue;">class</span> Program
{
<span style="color:Blue;">static</span> IntX Factorial(IntX n)
{
<span style="color:Blue;">if</span> (n < 0)
{
<span style="color:Blue;">throw</span> <span style="color:Blue;">new</span> ArgumentException(<span style="color:#A31515;">"Can't calculate factorial for negative number."</span>, <span style="color:#A31515;">"n"</span>);
}
<span style="color:Blue;">return</span> n == 0 ? 1 : n * Factorial(n - 1);
}
<span style="color:Blue;">static</span> <span style="color:Blue;">void</span> Main()
{
Console.WriteLine(Factorial(10000));
}
}
}
</pre></div>As you can see, IntX implements all the standard arithmetic operators so its usage is transparent for developer - like if you're working with usual integer.<br /><br /><b>FHT and Calculations Precision</b><br />Internally IntX library operates with floating-point numbers when multiplication using FHT is performed so at some point it stops working correctly and loses precision. Luckily, this unpleasant side-effects effects are starting to appear when integer size is about 2^28 bytes i.e. for really huge integers. Anyway, to catch such errors I have added FHT multiplication result validity check into code - it takes N last digits of each big integer, multiplies them using classic approach and then compares last N digits of classic result with last N digits of FHT result (so it's kind of simplified CRC check). If any inconsistency is found then FhtMultiplicationException is thrown; this check can be disabled using global settings.<br /><br /><b>Future Plans</b><br />I have no plans to further develop this library - I'm just sharing it with the community.<br /><br /><b>System.Numerics.BigInteger in .NET 4.0</b><br />According to the <a href="http://blogs.msdn.com/bclteam/archive/2008/11/04/what-s-new-in-the-bcl-in-net-4-0-justin-van-patten.aspx" class="externalLink">BCL team blog<span class="externalLinkIcon"></span></a> MS is going to introduce System.Numerics.BigInteger class in .NET 4.0, this time for sure :) Once I saw this blog entity I was interested in performance of their solution - you can download preliminary version together with <a href="http://code.msdn.microsoft.com/solverfoundation" class="externalLink">MS Solver Foundation<span class="externalLinkIcon"></span></a> (it's for .NET 3.5), it's called Microsoft.SolverFoundation.Common.BigInteger in there. I did some tests and it appears that BigInteger has performance in general comparable with IntX on standard operations but starts losing when FHT comes into play (when multiplying really big integers, for example).<br /><br />So internally System.Numerics.BigInteger seems to use standard arbitrary arithmetic algorithms and I am not worrying about IntX library since, due to its use of FHT, it can be times faster for really big integers.<br /><br /><b>Comparing IntX Performance to GMP</b><br />While IntX library is fast among other libraries written for .NET it can't really compete with <a href="http://gmplib.org/" class="externalLink">The GNU MP Library<span class="externalLinkIcon"></span></a> - one of the fastest well-known Bignum libraries in the world. GNU MP (or GMP) is written in plain C and Assembly language so it compiles into optimized native code, it also uses fast calculation algorithms - that's why it's very fast. I have compared IntX performance to GMP on basic arithmetic operations and it appeared that GMP is up to 8 times faster than IntX on certain operations. Actually for me it is a good result - IntX written in managed code is still quite fast :) GMP also has comparable performance on huge integers multiplication since, as well as IntX, it implements fast multiplication algorithm using FFT; it's also worth noticing that division for huge integers works few times faster in GMP comparing to IntX. GMP also has support for big floating-point numbers as well as for many numeric algorithms. For tests I was using <a href="javascript:window.location.href='http://intx.codeplex.com/Project/Download/FileDownload.aspx?DownloadId=102346';">libgmp-3.dll</a> GMP 5.0.0 DLL built for Windows using MinGW; I also want to add that my performance comparing was primitive and its results are very approximate.<br /><br />So if you need to perform a lot of operations with big integers and must get the fastest possible speed from them then I'd suggest you using <a href="http://gmplib.org/" class="externalLink">GMP<span class="externalLinkIcon"></span></a> (distributed under LGPL license); if you work in Windows you can build it with Cygwin/MinGW or use some GMP Windows-friendly port like <a href="http://www.mpir.org/" class="externalLink">MPIR<span class="externalLinkIcon"></span></a>. However, if 8x speed loss on some operations is okay for your project and/or you don't want to include unmanaged code into your application then IntX should be enough for you.<br /><br />Btw, using GMP from C# is quite easy because there are GMP C#-wrappers available <a href="http://www.emilstefanov.net/Projects/GnuMpDotNet/" class="externalLink">here<span class="externalLinkIcon"></span></a> (this one I was using for tests) and <a href="http://gnumpnet.codeplex.com/" class="externalLink">there<span class="externalLinkIcon"></span></a>. But be careful with them - both wrappers I saw are releasing unmanaged resource they are referring (which is memory) only in Finalize() method override and not implementing IDisposable so you can end with unexpected OutOfMemoryException as I did.</div><div class="ClearBoth"></div>OysterFri, 22 Jan 2010 22:33:18 GMTUpdated Wiki: Home 20100122103318PUpdated Wiki: Homehttp://intx.codeplex.com/wikipage?version=29<div class="wikidoc"><b>Project Description</b><br />IntX is an arbitrary precision integers library written in pure C# 2.0 with fast - O(N * log N) - multiplication/division algorithms implementation. It provides all the basic operations on integers like addition, multiplication, comparing, bitwise shifting etc. It also allows parsing numbers in base from 2 to 16 and converting them to string, also in any base. The advantage of this library is fast multiplication, division and from base/to base conversion algorithms - all the fast versions of the algorithms are based on fast multiplication of big integers using Fast Hartley Transform which runs for O(N * log N * log log N) time instead of classic O(N^2).<br /><br /><b>Bits of History</b><br />I have written IntX basically because I like big numbers and had some free time. Initial implementation was standard - I was using standard big integers +, -, *, / algorithms from Khuth book. After library was written I've decided to participate in contest held by <a href="http://gotdotnet.ru/" class="externalLink">GotDotNet.ru<span class="externalLinkIcon"></span></a> and received some replies which were saying that my library is too ... usual. Well, it was true, so I've decided to implement some more interesting algorithms in it.<br /><br />I've started with writing multiplication using <a href="http://en.wikipedia.org/wiki/Discrete_Hartley_transform" class="externalLink">Fast Hartley Transform<span class="externalLinkIcon"></span></a> so big integers multiplication time estimate became to be O(N * log N * log log N) (here N is amount of DWORDs in number representation) which was a bit better then O(N^2) with classic algorithm :) Then I saw fast algorithm for transforming from one base to another in Knuth book; it was based on fast multiplication so Parse()/ToString() started working faster - O(N * (log N)^2) instead of O(N^2). Finally division was also optimized (again, with the help of fast multiplication) - became as fast as multiplication.<br /><br />All this happened in 2005 year and in 2008 I've decided to publish this library on CodePlex - maybe it will be useful for someone out there (well, there is not so many similar libraries under .NET; also System.Numeric.BigInteger from .NET FW 3.5 was cancelled). Before publishing it on CodePlex I also made some cosmetic changes in code - used new .NET 2.0 features like generics (to minimize code duplication) and rewritten unit tests to use NUnit (they were previously written for MbUnit which is almost unknown and not used by community).<br /><br /><b>Code Example</b><br />Here is the sample of code which uses IntX and calculates 42 in power 1048576 (which is 2^20):<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">using</span> System;
<span style="color:Blue;">using</span> System.Diagnostics;
<span style="color:Blue;">using</span> Oyster.Math;
<span style="color:Blue;">namespace</span> IntxTestApp
{
<span style="color:Blue;">class</span> Program
{
<span style="color:Blue;">static</span> <span style="color:Blue;">void</span> Calc()
{
Stopwatch sw = Stopwatch.StartNew();
IntX.Pow(42, 1 << 20);
sw.Stop();
Console.WriteLine(<span style="color:#A31515;">"{0} ms"</span>, sw.ElapsedMilliseconds);
}
<span style="color:Blue;">static</span> <span style="color:Blue;">void</span> Main()
{
Calc();
IntX.GlobalSettings.MultiplyMode = MultiplyMode.Classic;
Calc();
}
}
}
</pre></div>First Calc() call uses fast multiplication implementation (which is default), second - classic one. On my machine (Win XP Pro SP2, P4 2.8 GHz, 2 GB RAM) first call is <b>70 times</b> faster than the second one (1 second against 68 seconds). Resulting number has 1,702,101 digits; you can get it here: <a href="javascript:window.location.href='http://intx.codeplex.com/Project/Download/FileDownload.aspx?DownloadId=27428';">42pow1048576.txt</a>.<br /><br />Another example is factorial calculation:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">using</span> System;
<span style="color:Blue;">using</span> Oyster.Math;
<span style="color:Blue;">namespace</span> IntxTestApp
{
<span style="color:Blue;">class</span> Program
{
<span style="color:Blue;">static</span> IntX Factorial(IntX n)
{
<span style="color:Blue;">if</span> (n < 0)
{
<span style="color:Blue;">throw</span> <span style="color:Blue;">new</span> ArgumentException(<span style="color:#A31515;">"Can't calculate factorial for negative number."</span>, <span style="color:#A31515;">"n"</span>);
}
<span style="color:Blue;">return</span> n == 0 ? 1 : n * Factorial(n - 1);
}
<span style="color:Blue;">static</span> <span style="color:Blue;">void</span> Main()
{
Console.WriteLine(Factorial(10000));
}
}
}
</pre></div>As you can see, IntX implements all the standard arithmetic operators so its usage is transparent for developer - like if you're working with usual integer.<br /><br /><b>FHT and Calculations Precision</b><br />Internally IntX library operates with floating-point numbers when multiplication using FHT is performed so at some point it stops working correctly and loses precision. Luckily, this unpleasant side-effects effects are starting to appear when integer size is about 2^28 bytes i.e. for really huge integers. Anyway, to catch such errors I have added FHT multiplication result validity check into code - it takes N last digits of each big integer, multiplies them using classic approach and then compares last N digits of classic result with last N digits of FHT result (so it's kind of simplified CRC check). If any inconsistency is found then FhtMultiplicationException is thrown; this check can be disabled using global settings.<br /><br /><b>Future Plans</b><br />I have no plans to further develop this library - I'm just sharing it with the community.<br /><br /><b>System.Numerics.BigInteger in .NET 4.0</b><br />According to the <a href="http://blogs.msdn.com/bclteam/archive/2008/11/04/what-s-new-in-the-bcl-in-net-4-0-justin-van-patten.aspx" class="externalLink">BCL team blog<span class="externalLinkIcon"></span></a> MS is going to introduce System.Numerics.BigInteger class in .NET 4.0, this time for sure :) Once I saw this blog entity I was interested in performance of their solution - you can download preliminary version together with <a href="http://code.msdn.microsoft.com/solverfoundation" class="externalLink">MS Solver Foundation<span class="externalLinkIcon"></span></a> (it's for .NET 3.5), it's called Microsoft.SolverFoundation.Common.BigInteger in there. I did some tests and it appears that BigInteger has performance in general comparable with IntX on standard operations but starts losing when FHT comes into play (when multiplying really big integers, for example).<br /><br />So internally System.Numerics.BigInteger seems to use standard arbitrary arithmetic algorithms and I am not worrying about IntX library since, due to its use of FHT, it can be times faster for really big integers.<br /><br /><b>Comparing IntX Performance to GMP</b><br />While IntX library is fast among other libraries written for .NET it can't really compete with <a href="http://gmplib.org/" class="externalLink">The GNU MP Library<span class="externalLinkIcon"></span></a> - one of the fastest well-known Bignum libraries in the world. GNU MP (or GMP) is written in plain C and Assembly language so it compiles into optimized native code, it also uses fast calculation algorithms - that's why it's very fast. I have compared IntX performance to GMP on basic arithmetic operations and it appeared that GMP is up to 8 times faster than IntX on certain operations. Actually for me it is a good result - IntX written in managed code is still quite fast :) GMP also has comparable performance on huge integers multiplication since, as well as IntX, it implements fast multiplication algorithm using FFT; it's also worth noticing that division for huge integers works few times faster in GMP comparing to IntX. GMP also has support for big floating-point numbers as well as for many numeric algorithms. For tests I was using <a href="javascript:window.location.href='http://intx.codeplex.com/Project/Download/FileDownload.aspx?DownloadId=102346';">libgmp-3.dll</a> GMP 5.0.0 DLL built for Windows using MinGW; I also want to add that my performance comparing was primitive and its results are very approximate.<br /><br />So if you need to perform a lot of operations with big integers and must get the fastest possible speed from them then I'd suggest you using <a href="http://gmplib.org/" class="externalLink">GMP<span class="externalLinkIcon"></span></a> (distributed under LGPL license); if you work in Windows you can build it with Cygwin/MinGW or use some GMP Windows-friendly port like <a href="http://www.mpir.org/" class="externalLink">MPIR<span class="externalLinkIcon"></span></a>. However, if 8x speed loss on some operations is okay for your project and/or you don't want to include unmanaged code into your application then IntX should be enough for you.<br /><br />Btw, using GMP from C# is quite easy because there are GMP C#-wrappers available <a href="http://www.emilstefanov.net/Projects/GnuMpDotNet/" class="externalLink">here<span class="externalLinkIcon"></span></a> (this one I was using for tests) and <a href="http://gnumpnet.codeplex.com/" class="externalLink">there<span class="externalLinkIcon"></span></a>. But be careful with them - both wrappers I saw are releasing unmanaged resource they are referring (which is memory) only in Finalize() method override and not implementing IDisposable so you can end with unexpected OutOfMemoryException as I did.</div><div class="ClearBoth"></div>OysterThu, 21 Jan 2010 16:34:45 GMTUpdated Wiki: Home 20100121043445PUpdated Wiki: Homehttp://intx.codeplex.com/wikipage?version=28<div class="wikidoc"><b>Project Description</b><br />IntX is an arbitrary precision integers library written in pure C# 2.0 with fast - O(N * log N) - multiplication/division algorithms implementation. It provides all the basic operations on integers like addition, multiplication, comparing, bitwise shifting etc. It also allows parsing numbers in base from 2 to 16 and converting them to string, also in any base. The advantage of this library is fast multiplication, division and from base/to base conversion algorithms - all the fast versions of the algorithms are based on fast multiplication of big integers using Fast Hartley Transform which runs for O(N * log N * log log N) time instead of classic O(N^2).<br /><br /><b>Bits of History</b><br />I have written IntX basically because I like big numbers and had some free time. Initial implementation was standard - I was using standard big integers +, -, *, / algorithms from Khuth book. After library was written I've decided to participate in <a href="http://contest2005.gotdotnet.ru/Request/Tools/UtilitiesLib/169728.aspx" class="externalLink">contest held by GotDotNet.ru site<span class="externalLinkIcon"></span></a> and received some replies which were saying that my library is too ... usual. Well, it was true, so I've decided to implement some more interesting algorithms in it.<br /><br />I've started with writing multiplication using <a href="http://en.wikipedia.org/wiki/Discrete_Hartley_transform" class="externalLink">Fast Hartley Transform<span class="externalLinkIcon"></span></a> so big integers multiplication time estimate became to be O(N * log N * log log N) (here N is amount of DWORDs in number representation) which was a bit better then O(N^2) with classic algorithm :) Then I saw fast algorithm for transforming from one base to another in Knuth book; it was based on fast multiplication so Parse()/ToString() started working faster - O(N * (log N)^2) instead of O(N^2). Finally division was also optimized (again, with the help of fast multiplication) - became as fast as multiplication.<br /><br />All this happened in 2005 year and in 2008 I've decided to publish this library on CodePlex - maybe it will be useful for someone out there (well, there is not so many similar libraries under .NET; also System.Numeric.BigInteger from .NET FW 3.5 was cancelled). Before publishing it on CodePlex I also made some cosmetic changes in code - used new .NET 2.0 features like generics (to minimize code duplication) and rewritten unit tests to use NUnit (they were previously written for MbUnit which is almost unknown and not used by community).<br /><br /><b>Code Example</b><br />Here is the sample of code which uses IntX and calculates 42 in power 1048576 (which is 2^20):<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">using</span> System;
<span style="color:Blue;">using</span> System.Diagnostics;
<span style="color:Blue;">using</span> Oyster.Math;
<span style="color:Blue;">namespace</span> IntxTestApp
{
<span style="color:Blue;">class</span> Program
{
<span style="color:Blue;">static</span> <span style="color:Blue;">void</span> Calc()
{
Stopwatch sw = Stopwatch.StartNew();
IntX.Pow(42, 1 << 20);
sw.Stop();
Console.WriteLine(<span style="color:#A31515;">"{0} ms"</span>, sw.ElapsedMilliseconds);
}
<span style="color:Blue;">static</span> <span style="color:Blue;">void</span> Main()
{
Calc();
IntX.GlobalSettings.MultiplyMode = MultiplyMode.Classic;
Calc();
}
}
}
</pre></div>First Calc() call uses fast multiplication implementation (which is default), second - classic one. On my machine (Win XP Pro SP2, P4 2.8 GHz, 2 GB RAM) first call is <b>70 times</b> faster than the second one (1 second against 68 seconds). Resulting number has 1,702,101 digits; you can get it here: <a href="javascript:window.location.href='http://intx.codeplex.com/Project/Download/FileDownload.aspx?DownloadId=27428';">42pow1048576.txt</a>.<br /><br />Another example is factorial calculation:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">using</span> System;
<span style="color:Blue;">using</span> Oyster.Math;
<span style="color:Blue;">namespace</span> IntxTestApp
{
<span style="color:Blue;">class</span> Program
{
<span style="color:Blue;">static</span> IntX Factorial(IntX n)
{
<span style="color:Blue;">if</span> (n < 0)
{
<span style="color:Blue;">throw</span> <span style="color:Blue;">new</span> ArgumentException(<span style="color:#A31515;">"Can't calculate factorial for negative number."</span>, <span style="color:#A31515;">"n"</span>);
}
<span style="color:Blue;">return</span> n == 0 ? 1 : n * Factorial(n - 1);
}
<span style="color:Blue;">static</span> <span style="color:Blue;">void</span> Main()
{
Console.WriteLine(Factorial(10000));
}
}
}
</pre></div>As you can see, IntX implements all the standard arithmetic operators so its usage is transparent for developer - like if you're working with usual integer.<br /><br /><b>FHT and Calculations Precision</b><br />Internally IntX library operates with floating-point numbers when multiplication using FHT is performed so at some point it stops working correctly and loses precision. Luckily, this unpleasant side-effects effects are starting to appear when integer size is about 2^28 bytes i.e. for really huge integers. Anyway, to catch such errors I have added FHT multiplication result validity check into code - it takes N last digits of each big integer, multiplies them using classic approach and then compares last N digits of classic result with last N digits of FHT result (so it's kind of simplified CRC check). If any inconsistency is found then FhtMultiplicationException is thrown; this check can be disabled using global settings.<br /><br /><b>Future Plans</b><br />I have no plans to further develop this library - I'm just sharing it with the community.<br /><br /><b>System.Numerics.BigInteger in .NET 4.0</b><br />According to the <a href="http://blogs.msdn.com/bclteam/archive/2008/11/04/what-s-new-in-the-bcl-in-net-4-0-justin-van-patten.aspx" class="externalLink">BCL team blog<span class="externalLinkIcon"></span></a> MS is going to introduce System.Numerics.BigInteger class in .NET 4.0, this time for sure :) Once I saw this blog entity I was interested in performance of their solution - you can download preliminary version together with <a href="http://code.msdn.microsoft.com/solverfoundation" class="externalLink">MS Solver Foundation<span class="externalLinkIcon"></span></a> (it's for .NET 3.5), it's called Microsoft.SolverFoundation.Common.BigInteger in there. I did some tests and it appears that BigInteger has performance in general comparable with IntX on standard operations but starts losing when FHT comes into play (when multiplying really big integers, for example).<br /><br />So internally System.Numerics.BigInteger seems to use standard arbitrary arithmetic algorithms and I am not worrying about IntX library since, due to its use of FHT, it can be times faster for really big integers.<br /><br /><b>Comparing IntX Performance to GMP</b><br />While IntX library is fast among other libraries written for .NET it can't really compete with <a href="http://gmplib.org/" class="externalLink">The GNU MP Library<span class="externalLinkIcon"></span></a> - one of the fastest well-known Bignum libraries in the world. GNU MP (or GMP) is written in plain C and Assembly language so it compiles into optimized native code, it also uses fast calculation algorithms - that's why it's very fast. I have compared IntX performance to GMP on basic arithmetic operations and it appeared that GMP is up to 8 times faster than IntX on certain operations. Actually for me it is a good result - IntX written in managed code is still quite fast :) GMP also has comparable performance on huge integers multiplication since, as well as IntX, it implements fast multiplication algorithm using FFT; it's also worth noticing that division for huge integers works few times faster in GMP comparing to IntX. GMP also has support for big floating-point numbers as well as for many numeric algorithms. For tests I was using <a href="javascript:window.location.href='http://intx.codeplex.com/Project/Download/FileDownload.aspx?DownloadId=102346';">libgmp-3.dll</a> GMP 5.0.0 DLL built for Windows using MinGW; I also want to add that my performance comparing was primitive and its results are very approximate.<br /><br />So if you need to perform a lot of operations with big integers and must get the fastest possible speed from them then I'd suggest you using <a href="http://gmplib.org/" class="externalLink">GMP<span class="externalLinkIcon"></span></a> (distributed under LGPL license); if you work in Windows you can build it with Cygwin/MinGW or use some GMP Windows-friendly port like <a href="http://www.mpir.org/" class="externalLink">MPIR<span class="externalLinkIcon"></span></a>. However, if 8x speed loss on some operations is okay for your project and/or you don't want to include unmanaged code into your application then IntX should be enough for you.<br /><br />Btw, using GMP from C# is quite easy because there are GMP C#-wrappers available <a href="http://www.emilstefanov.net/Projects/GnuMpDotNet/" class="externalLink">here<span class="externalLinkIcon"></span></a> (this one I was using for tests) and <a href="http://gnumpnet.codeplex.com/" class="externalLink">there<span class="externalLinkIcon"></span></a>. But be careful with them - both wrappers I saw are releasing unmanaged resource they are referring (which is memory) only in Finalize() method override and not implementing IDisposable so you can end with unexpected OutOfMemoryException as I did.</div><div class="ClearBoth"></div>OysterThu, 21 Jan 2010 14:43:02 GMTUpdated Wiki: Home 20100121024302PUpdated Wiki: Homehttp://intx.codeplex.com/wikipage?version=27<div class="wikidoc"><b>Project Description</b><br />IntX is an arbitrary precision integers library written in pure C# 2.0 with fast - O(N * log N) - multiplication/division algorithms implementation. It provides all the basic operations on integers like addition, multiplication, comparing, bitwise shifting etc. It also allows parsing numbers in base from 2 to 16 and converting them to string, also in any base. The advantage of this library is fast multiplication, division and from base/to base conversion algorithms - all the fast versions of the algorithms are based on fast multiplication of big integers using Fast Hartley Transform which runs for O(N * log N * log log N) time instead of classic O(N^2).<br /><br /><b>Bits of History</b><br />I have written IntX basically because I like big numbers and had some free time. Initial implementation was standard - I was using standard big integers +, -, *, / algorithms from Khuth book. After library was written I've decided to participate in <a href="http://contest2005.gotdotnet.ru/Request/Tools/UtilitiesLib/169728.aspx" class="externalLink">contest held by GotDotNet.ru site<span class="externalLinkIcon"></span></a> and received some replies which were saying that my library is too ... usual. Well, it was true, so I've decided to implement some more interesting algorithms in it.<br /><br />I've started with writing multiplication using <a href="http://en.wikipedia.org/wiki/Discrete_Hartley_transform" class="externalLink">Fast Hartley Transform<span class="externalLinkIcon"></span></a> so big integers multiplication time estimate became to be O(N * log N * log log N) (here N is amount of DWORDs in number representation) which was a bit better then O(N^2) with classic algorithm :) Then I saw fast algorithm for transforming from one base to another in Knuth book; it was based on fast multiplication so Parse()/ToString() started working faster - O(N * (log N)^2) instead of O(N^2). Finally division was also optimized (again, with the help of fast multiplication) - became as fast as multiplication.<br /><br />All this happened in 2005 year and in 2008 I've decided to publish this library on CodePlex - maybe it will be useful for someone out there (well, there is not so many similar libraries under .NET; also System.Numeric.BigInteger from .NET FW 3.5 was cancelled). Before publishing it on CodePlex I also made some cosmetic changes in code - used new .NET 2.0 features like generics (to minimize code duplication) and rewritten unit tests to use NUnit (they were previously written for MbUnit which is almost unknown and not used by community).<br /><br /><b>Code Example</b><br />Here is the sample of code which uses IntX and calculates 42 in power 1048576 (which is 2^20):<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">using</span> System;
<span style="color:Blue;">using</span> System.Diagnostics;
<span style="color:Blue;">using</span> Oyster.Math;
<span style="color:Blue;">namespace</span> IntxTestApp
{
<span style="color:Blue;">class</span> Program
{
<span style="color:Blue;">static</span> <span style="color:Blue;">void</span> Calc()
{
Stopwatch sw = Stopwatch.StartNew();
IntX.Pow(42, 1 << 20);
sw.Stop();
Console.WriteLine(<span style="color:#A31515;">"{0} ms"</span>, sw.ElapsedMilliseconds);
}
<span style="color:Blue;">static</span> <span style="color:Blue;">void</span> Main()
{
Calc();
IntX.GlobalSettings.MultiplyMode = MultiplyMode.Classic;
Calc();
}
}
}
</pre></div>First Calc() call uses fast multiplication implementation (which is default), second - classic one. On my machine (Win XP Pro SP2, P4 2.8 GHz, 2 GB RAM) first call is <b>70 times</b> faster than the second one (1 second against 68 seconds). Resulting number has 1,702,101 digits; you can get it here: <a href="javascript:window.location.href='http://intx.codeplex.com/Project/Download/FileDownload.aspx?DownloadId=27428';">42pow1048576.txt</a>.<br /><br />Another example is factorial calculation:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">using</span> System;
<span style="color:Blue;">using</span> Oyster.Math;
<span style="color:Blue;">namespace</span> IntxTestApp
{
<span style="color:Blue;">class</span> Program
{
<span style="color:Blue;">static</span> IntX Factorial(IntX n)
{
<span style="color:Blue;">if</span> (n < 0)
{
<span style="color:Blue;">throw</span> <span style="color:Blue;">new</span> ArgumentException(<span style="color:#A31515;">"Can't calculate factorial for negative number."</span>, <span style="color:#A31515;">"n"</span>);
}
<span style="color:Blue;">return</span> n == 0 ? 1 : n * Factorial(n - 1);
}
<span style="color:Blue;">static</span> <span style="color:Blue;">void</span> Main()
{
Console.WriteLine(Factorial(10000));
}
}
}
</pre></div>As you can see, IntX implements all the standard arithmetic operators so its usage is transparent for developer - like if you're working with usual integer.<br /><br /><b>FHT and Calculations Precision</b><br />Internally IntX library operates with floating-point numbers when multiplication using FHT is performed so at some point it stops working correctly and loses precision. Luckily, this unpleasant side-effects effects are starting to appear when integer size is about 2^28 bytes i.e. for really huge integers. Anyway, to catch such errors I have added FHT multiplication result validity check into code - it takes N last digits of each big integer, multiplies them using classic approach and then compares last N digits of classic result with last N digits of FHT result (so it's kind of simplified CRC check). If any inconsistency is found then FhtMultiplicationException is thrown; this check can be disabled using global settings.<br /><br /><b>Future Plans</b><br />I have no plans to further develop this library - I'm just sharing it with the community.<br /><br /><b>System.Numerics.BigInteger in .NET 4.0</b><br />According to the <a href="http://blogs.msdn.com/bclteam/archive/2008/11/04/what-s-new-in-the-bcl-in-net-4-0-justin-van-patten.aspx" class="externalLink">BCL team blog<span class="externalLinkIcon"></span></a> MS is going to introduce System.Numerics.BigInteger class in .NET 4.0, this time for sure :) Once I saw this blog entity I was interested in performance of their solution - you can download preliminary version together with <a href="http://code.msdn.microsoft.com/solverfoundation" class="externalLink">MS Solver Foundation<span class="externalLinkIcon"></span></a> (it's for .NET 3.5), it's called Microsoft.SolverFoundation.Common.BigInteger in there. I did some tests and it appears that BigInteger has performance in general comparable with IntX on standard operations but starts losing when FHT comes into play (when multiplying really big integers, for example).<br /><br />So internally System.Numerics.BigInteger seems to use standard arbitrary arithmetic algorithms and I am not worrying about IntX library since, due to its use of FHT, it can be times faster for really big integers.<br /><br /><b>Comparing IntX Performance to GMP</b><br />While IntX library is fast among other libraries written for .NET it can't really compete with <a href="http://gmplib.org/" class="externalLink">The GNU MP Library<span class="externalLinkIcon"></span></a> - one of the fastest well-known Bignum libraries in the world. GNU MP (or GMP) is written in plain C and Assembly language so it compiles into optimized native code, it also uses fast calculation algorithms - that's why it's very fast. I have compared IntX performance to GMP on basic arithmetic operations and it appeared that GMP is up to 8 times faster than IntX on certain operations. Actually for me it is a good result - IntX written in managed code is still quite fast :) GMP also has comparable performance on huge integers multiplication since, as well as IntX, it implements fast multiplication algorithm using FFT; it's also worth noticing that division for huge integers works few times faster in GMP comparing to IntX. GMP also has support for big floating-point numbers as well as for many numeric algorithms. For tests I was using <a href="javascript:window.location.href='http://intx.codeplex.com/Project/Download/FileDownload.aspx?DownloadId=102346';">libgmp-3.dll</a> GMP 5.0.0 DLL built for Windows using MinGW; I also want to add that my performance comparing was primitive and its results are very approximate.<br /><br />So if you need to perform a lot of operations with big integers and must get the fastest possible speed from them then I'd suggest you using <a href="http://gmplib.org/" class="externalLink">GMP<span class="externalLinkIcon"></span></a> (distributed under LGPL license); if you work in Windows you can build it with Cygwin/MinGW or use some GMP Windows-friendly port like <a href="http://www.mpir.org/" class="externalLink">MPIR<span class="externalLinkIcon"></span></a>. However, if 8x speed loss on some operations is okay for your project and/or you don't want to include unmanaged code into your application then IntX should be enough for you.<br /><br />Btw, using GMP from C# is quite easy because there are GMP C#-wrappers available <a href="http://www.emilstefanov.net/Projects/GnuMpDotNet/" class="externalLink">here<span class="externalLinkIcon"></span></a> (this one I was using for tests; I was also using GMP DLL which comes with it) and <a href="http://gnumpnet.codeplex.com/" class="externalLink">there<span class="externalLinkIcon"></span></a>. But be careful with them - both wrappers I saw are releasing unmanaged resource they are referring (which is memory) only in Finalize() method override and not implementing IDisposable so you can end with unexpected OutOfMemoryException as I did.</div><div class="ClearBoth"></div>OysterThu, 21 Jan 2010 14:42:18 GMTUpdated Wiki: Home 20100121024218PUpdated Wiki: Homehttp://intx.codeplex.com/wikipage?version=26<div class="wikidoc"><b>Project Description</b><br />IntX is an arbitrary precision integers library written in pure C# 2.0 with fast - O(N * log N) - multiplication/division algorithms implementation. It provides all the basic operations on integers like addition, multiplication, comparing, bitwise shifting etc. It also allows parsing numbers in base from 2 to 16 and converting them to string, also in any base. The advantage of this library is fast multiplication, division and from base/to base conversion algorithms - all the fast versions of the algorithms are based on fast multiplication of big integers using Fast Hartley Transform which runs for O(N * log N * log log N) time instead of classic O(N^2).<br /><br /><b>Bits of History</b><br />I have written IntX basically because I like big numbers and had some free time. Initial implementation was standard - I was using standard big integers +, -, *, / algorithms from Khuth book. After library was written I've decided to participate in <a href="http://contest2005.gotdotnet.ru/Request/Tools/UtilitiesLib/169728.aspx" class="externalLink">contest held by GotDotNet.ru site<span class="externalLinkIcon"></span></a> and received some replies which were saying that my library is too ... usual. Well, it was true, so I've decided to implement some more interesting algorithms in it.<br /><br />I've started with writing multiplication using <a href="http://en.wikipedia.org/wiki/Discrete_Hartley_transform" class="externalLink">Fast Hartley Transform<span class="externalLinkIcon"></span></a> so big integers multiplication time estimate became to be O(N * log N * log log N) (here N is amount of DWORDs in number representation) which was a bit better then O(N^2) with classic algorithm :) Then I saw fast algorithm for transforming from one base to another in Knuth book; it was based on fast multiplication so Parse()/ToString() started working faster - O(N * (log N)^2) instead of O(N^2). Finally division was also optimized (again, with the help of fast multiplication) - became as fast as multiplication.<br /><br />All this happened in 2005 year and in 2008 I've decided to publish this library on CodePlex - maybe it will be useful for someone out there (well, there is not so many similar libraries under .NET; also System.Numeric.BigInteger from .NET FW 3.5 was cancelled). Before publishing it on CodePlex I also made some cosmetic changes in code - used new .NET 2.0 features like generics (to minimize code duplication) and rewritten unit tests to use NUnit (they were previously written for MbUnit which is almost unknown and not used by community).<br /><br /><b>Code Example</b><br />Here is the sample of code which uses IntX and calculates 42 in power 1048576 (which is 2^20):<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">using</span> System;
<span style="color:Blue;">using</span> System.Diagnostics;
<span style="color:Blue;">using</span> Oyster.Math;
<span style="color:Blue;">namespace</span> IntxTestApp
{
<span style="color:Blue;">class</span> Program
{
<span style="color:Blue;">static</span> <span style="color:Blue;">void</span> Calc()
{
Stopwatch sw = Stopwatch.StartNew();
IntX.Pow(42, 1 << 20);
sw.Stop();
Console.WriteLine(<span style="color:#A31515;">"{0} ms"</span>, sw.ElapsedMilliseconds);
}
<span style="color:Blue;">static</span> <span style="color:Blue;">void</span> Main()
{
Calc();
IntX.GlobalSettings.MultiplyMode = MultiplyMode.Classic;
Calc();
}
}
}
</pre></div>First Calc() call uses fast multiplication implementation (which is default), second - classic one. On my machine (Win XP Pro SP2, P4 2.8 GHz, 2 GB RAM) first call is <b>70 times</b> faster than the second one (1 second against 68 seconds). Resulting number has 1,702,101 digits; you can get it here: <a href="javascript:window.location.href='http://intx.codeplex.com/Project/Download/FileDownload.aspx?DownloadId=27428';">42pow1048576.txt</a>.<br /><br />Another example is factorial calculation:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">using</span> System;
<span style="color:Blue;">using</span> Oyster.Math;
<span style="color:Blue;">namespace</span> IntxTestApp
{
<span style="color:Blue;">class</span> Program
{
<span style="color:Blue;">static</span> IntX Factorial(IntX n)
{
<span style="color:Blue;">if</span> (n < 0)
{
<span style="color:Blue;">throw</span> <span style="color:Blue;">new</span> ArgumentException(<span style="color:#A31515;">"Can't calculate factorial for negative number."</span>, <span style="color:#A31515;">"n"</span>);
}
<span style="color:Blue;">return</span> n == 0 ? 1 : n * Factorial(n - 1);
}
<span style="color:Blue;">static</span> <span style="color:Blue;">void</span> Main()
{
Console.WriteLine(Factorial(10000));
}
}
}
</pre></div>As you can see, IntX implements all the standard arithmetic operators so its usage is transparent for developer - like if you're working with usual integer.<br /><br /><b>FHT and Calculations Precision</b><br />Internally IntX library operates with floating-point numbers when multiplication using FHT is performed so at some point it stops working correctly and loses precision. Luckily, this unpleasant side-effects effects are starting to appear when integer size is about 2^28 bytes i.e. for really huge integers. Anyway, to catch such errors I have added FHT multiplication result validity check into code - it takes N last digits of each big integer, multiplies them using classic approach and then compares last N digits of classic result with last N digits of FHT result (so it's kind of simplified CRC check). If any inconsistency is found then FhtMultiplicationException is thrown; this check can be disabled using global settings.<br /><br /><b>Future Plans</b><br />I have no plans to further develop this library - I'm just sharing it with the community.<br /><br /><b>System.Numerics.BigInteger in .NET 4.0</b><br />According to the <a href="http://blogs.msdn.com/bclteam/archive/2008/11/04/what-s-new-in-the-bcl-in-net-4-0-justin-van-patten.aspx" class="externalLink">BCL team blog<span class="externalLinkIcon"></span></a> MS is going to introduce System.Numerics.BigInteger class in .NET 4.0, this time for sure :) Once I saw this blog entity I was interested in performance of their solution - you can download preliminary version together with <a href="http://code.msdn.microsoft.com/solverfoundation" class="externalLink">MS Solver Foundation<span class="externalLinkIcon"></span></a> (it's for .NET 3.5), it's called Microsoft.SolverFoundation.Common.BigInteger in there. I did some tests and it appears that BigInteger has performance in general comparable with IntX on standard operations but starts losing when FHT comes into play (when multiplying really big integers, for example).<br /><br />So internally System.Numerics.BigInteger seems to use standard arbitrary arithmetic algorithms and I am not worrying about IntX library since, due to its use of FHT, it can be times faster for really big integers.<br /><br /><b>Comparing IntX Performance to GMP</b><br />While IntX library is fast among other libraries written for .NET it can't really compete with <a href="http://gmplib.org/" class="externalLink">The GNU MP Library<span class="externalLinkIcon"></span></a> - one of the fastest well-known Bignum libraries in the world. GNU MP (or GMP) is written in plain C and Assembly language so it compiles into optimized native code, it also uses fast calculation algorithms - that's why it's very fast. I have compared IntX performance to GMP on basic arithmetic operations and it appeared that GMP is up to 5 times faster than IntX. Actually for me it is a good result - IntX written in managed code is still quite fast :) GMP has about the same performance on huge integers multiplication since, as well as IntX, it implements fast multiplication algorithm using FFT; it's also worth noticing that division for huge integers works about 4x faster in GMP comparing to IntX. GMP also has support for big floating-point numbers as well as for many numeric algorithms.<br /><br />So if you need to perform a lot of operations with big integers and must get the fastest possible speed from them then I'd suggest you using <a href="http://gmplib.org/" class="externalLink">GMP<span class="externalLinkIcon"></span></a> (distributed under LGPL license). However, if 5x speed loss on some operations is okay for your project and/or you don't want to include unmanaged code into your application then IntX should be enough for you.<br /><br />Btw, using GMP from C# is quite easy because there are GMP C#-wrappers available <a href="http://www.emilstefanov.net/Projects/GnuMpDotNet/" class="externalLink">here<span class="externalLinkIcon"></span></a> (this one I was using for tests; I was also using GMP DLL which comes with it) and <a href="http://gnumpnet.codeplex.com/" class="externalLink">there<span class="externalLinkIcon"></span></a>. But be careful with them - both wrappers I saw are releasing unmanaged resource they are referring (which is memory) only in Finalize() method override and not implementing IDisposable so you can end with unexpected OutOfMemoryException as I did.</div><div class="ClearBoth"></div>OysterWed, 20 Jan 2010 17:54:54 GMTUpdated Wiki: Home 20100120055454PUpdated Wiki: Homehttp://intx.codeplex.com/wikipage?version=25<div class="wikidoc"><b>Project Description</b><br />IntX is an arbitrary precision integers library written in pure C# 2.0 with fast - O(N * log N) - multiplication/division algorithms implementation. It provides all the basic operations on integers like addition, multiplication, comparing, bitwise shifting etc. It also allows parsing numbers in base from 2 to 16 and converting them to string, also in any base. The advantage of this library is fast multiplication, division and from base/to base conversion algorithms - all the fast versions of the algorithms are based on fast multiplication of big integers using Fast Hartley Transform which runs for O(N * log N * log log N) time instead of classic O(N^2).<br /><br /><b>Bits of History</b><br />I have written IntX basically because I like big numbers and had some free time. Initial implementation was standard - I was using standard big integers +, -, *, / algorithms from Khuth book. After library was written I've decided to participate in <a href="http://contest2005.gotdotnet.ru/Request/Tools/UtilitiesLib/169728.aspx" class="externalLink">contest held by GotDotNet.ru site<span class="externalLinkIcon"></span></a> and received some replies which were saying that my library is too ... usual. Well, it was true, so I've decided to implement some more interesting algorithms in it.<br /><br />I've started with writing multiplication using <a href="http://en.wikipedia.org/wiki/Discrete_Hartley_transform" class="externalLink">Fast Hartley Transform<span class="externalLinkIcon"></span></a> so big integers multiplication time estimate became to be O(N * log N * log log N) (here N is amount of DWORDs in number representation) which was a bit better then O(N^2) with classic algorithm :) Then I saw fast algorithm for transforming from one base to another in Knuth book; it was based on fast multiplication so Parse()/ToString() started working faster - O(N * (log N)^2) instead of O(N^2). Finally division was also optimized (again, with the help of fast multiplication) - became as fast as multiplication.<br /><br />All this happened in 2005 year and in 2008 I've decided to publish this library on CodePlex - maybe it will be useful for someone out there (well, there is not so many similar libraries under .NET; also System.Numeric.BigInteger from .NET FW 3.5 was cancelled). Before publishing it on CodePlex I also made some cosmetic changes in code - used new .NET 2.0 features like generics (to minimize code duplication) and rewritten unit tests to use NUnit (they were previously written for MbUnit which is almost unknown and not used by community).<br /><br /><b>Code Example</b><br />Here is the sample of code which uses IntX and calculates 42 in power 1048576 (which is 2^20):<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">using</span> System;
<span style="color:Blue;">using</span> System.Diagnostics;
<span style="color:Blue;">using</span> Oyster.Math;
<span style="color:Blue;">namespace</span> IntxTestApp
{
<span style="color:Blue;">class</span> Program
{
<span style="color:Blue;">static</span> <span style="color:Blue;">void</span> Calc()
{
Stopwatch sw = Stopwatch.StartNew();
IntX.Pow(42, 1 << 20);
sw.Stop();
Console.WriteLine(<span style="color:#A31515;">"{0} ms"</span>, sw.ElapsedMilliseconds);
}
<span style="color:Blue;">static</span> <span style="color:Blue;">void</span> Main()
{
Calc();
IntX.GlobalSettings.MultiplyMode = MultiplyMode.Classic;
Calc();
}
}
}
</pre></div>First Calc() call uses fast multiplication implementation (which is default), second - classic one. On my machine (Win XP Pro SP2, P4 2.8 GHz, 2 GB RAM) first call is <b>70 times</b> faster than the second one (1 second against 68 seconds). Resulting number has 1,702,101 digits; you can get it here: <a href="javascript:window.location.href='http://intx.codeplex.com/Project/Download/FileDownload.aspx?DownloadId=27428';">42pow1048576.txt</a>.<br /><br />Another example is factorial calculation:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">using</span> System;
<span style="color:Blue;">using</span> Oyster.Math;
<span style="color:Blue;">namespace</span> IntxTestApp
{
<span style="color:Blue;">class</span> Program
{
<span style="color:Blue;">static</span> IntX Factorial(IntX n)
{
<span style="color:Blue;">if</span> (n < 0)
{
<span style="color:Blue;">throw</span> <span style="color:Blue;">new</span> ArgumentException(<span style="color:#A31515;">"Can't calculate factorial for negative number."</span>, <span style="color:#A31515;">"n"</span>);
}
<span style="color:Blue;">return</span> n == 0 ? 1 : n * Factorial(n - 1);
}
<span style="color:Blue;">static</span> <span style="color:Blue;">void</span> Main()
{
Console.WriteLine(Factorial(10000));
}
}
}
</pre></div>As you can see, IntX implements all the standard arithmetic operators so its usage is transparent for developer - like if you're working with usual integer.<br /><br /><b>FHT and Calculations Precision</b><br />Internally IntX library operates with floating-point numbers when multiplication using FHT is performed so at some point it stops working correctly and loses precision. Luckily, this unpleasant side-effects effects are starting to appear when integer size is about 2^28 bytes i.e. for really huge integers. Anyway, to catch such errors I have added FHT multiplication result validity check into code - it takes N last digits of each big integer, multiplies them using classic approach and then compares last N digits of classic result with last N digits of FHT result (so it's kind of simplified CRC check). If any inconsistency is found then FhtMultiplicationException is thrown; this check can be disabled using global settings.<br /><br /><b>Future Plans</b><br />I have no plans to further develop this library - I'm just sharing it with the community.<br /><br /><b>System.Numerics.BigInteger in .NET 4.0</b><br />According to the <a href="http://blogs.msdn.com/bclteam/archive/2008/11/04/what-s-new-in-the-bcl-in-net-4-0-justin-van-patten.aspx" class="externalLink">BCL team blog<span class="externalLinkIcon"></span></a> MS is going to introduce System.Numerics.BigInteger class in .NET 4.0, this time for sure :) Once I saw this blog entity I was interested in performance of their solution - you can download preliminary version together with <a href="http://code.msdn.microsoft.com/solverfoundation" class="externalLink">MS Solver Foundation<span class="externalLinkIcon"></span></a> (it's for .NET 3.5), it's called Microsoft.SolverFoundation.Common.BigInteger in there. I did some tests and it appears that BigInteger has performance in general comparable with IntX on standard operations but starts losing when FHT comes into play (when multiplying really big integers, for example).<br /><br />So internally System.Numerics.BigInteger seems to use standard arbitrary arithmetic algorithms and I am not worrying about IntX library since, due to its use of FHT, it can be times faster for really big integers.<br /><br /><b>Comparing IntX Performance to GMP</b><br />While IntX library is fast among other libraries written for .NET it can't really compete with <a href="http://gmplib.org/" class="externalLink">The GNU MP Library<span class="externalLinkIcon"></span></a> - one of the fastest well-known Bignum libraries in the world. GNU MP (or GMP) is written in plain C and Assembly language so it compiles into optimized native code, it also uses fast calculation algorithms - that's why it's very fast. I have compared IntX performance to GMP on basic arithmetic operations and it appeared that GMP is up to 5 times faster than IntX. Actually for me it is a good result - IntX written in managed code is still quite fast :) GMP has about the same performance on huge integers multiplication since, as well as IntX, it implements fast multiplication algorithm using FFT; it's also worth noticing that division for huge integers works about 4x faster in GMP comparing to IntX. GMP also has support for big floating-point numbers.<br /><br />So if you need to perform a lot of operations with big integers and must get the fastest possible speed from them then I'd suggest you using <a href="http://gmplib.org/" class="externalLink">GMP<span class="externalLinkIcon"></span></a> (distributed under LGPL license). However, if 5x speed loss on some operations is okay for your project and/or you don't want to include unmanaged code into your application then IntX should be enough for you.<br /><br />Btw, using GMP from C# is quite easy because there are GMP C#-wrappers available <a href="http://www.emilstefanov.net/Projects/GnuMpDotNet/" class="externalLink">here<span class="externalLinkIcon"></span></a> (this one I was using for tests; I was also using GMP DLL which comes with it) and <a href="http://gnumpnet.codeplex.com/" class="externalLink">there<span class="externalLinkIcon"></span></a>. But be careful with them - both wrappers I saw are releasing unmanaged resource they are referring (which is memory) only in Finalize() method override and not implementing IDisposable so you can end with unexpected OutOfMemoryException as I did.</div><div class="ClearBoth"></div>OysterWed, 20 Jan 2010 17:52:47 GMTUpdated Wiki: Home 20100120055247PUpdated Wiki: Homehttp://intx.codeplex.com/wikipage?version=24<div class="wikidoc"><b>Project Description</b><br />IntX is an arbitrary precision integers library written in pure C# 2.0 with fast - O(N * log N) - multiplication/division algorithms implementation. It provides all the basic operations on integers like addition, multiplication, comparing, bitwise shifting etc. It also allows parsing numbers in base from 2 to 16 and converting them to string, also in any base. The advantage of this library is fast multiplication, division and from base/to base conversion algorithms - all the fast versions of the algorithms are based on fast multiplication of big integers using Fast Hartley Transform which runs for O(N * log N * log log N) time instead of classic O(N^2).<br /><br /><b>Bits of History</b><br />I have written IntX basically because I like big numbers and had some free time. Initial implementation was standard - I was using standard big integers +, -, *, / algorithms from Khuth book. After library was written I've decided to participate in <a href="http://contest2005.gotdotnet.ru/Request/Tools/UtilitiesLib/169728.aspx" class="externalLink">contest held by GotDotNet.ru site<span class="externalLinkIcon"></span></a> and received some replies which were saying that my library is too ... usual. Well, it was true, so I've decided to implement some more interesting algorithms in it.<br /><br />I've started with writing multiplication using <a href="http://en.wikipedia.org/wiki/Discrete_Hartley_transform" class="externalLink">Fast Hartley Transform<span class="externalLinkIcon"></span></a> so big integers multiplication time estimate became to be O(N * log N * log log N) (here N is amount of DWORDs in number representation) which was a bit better then O(N^2) with classic algorithm :) Then I saw fast algorithm for transforming from one base to another in Knuth book; it was based on fast multiplication so Parse()/ToString() started working faster - O(N * (log N)^2) instead of O(N^2). Finally division was also optimized (again, with the help of fast multiplication) - became as fast as multiplication.<br /><br />All this happened in 2005 year and in 2008 I've decided to publish this library on CodePlex - maybe it will be useful for someone out there (well, there is not so many similar libraries under .NET; also System.Numeric.BigInteger from .NET FW 3.5 was cancelled). Before publishing it on CodePlex I also made some cosmetic changes in code - used new .NET 2.0 features like generics (to minimize code duplication) and rewritten unit tests to use NUnit (they were previously written for MbUnit which is almost unknown and not used by community).<br /><br /><b>Code Example</b><br />Here is the sample of code which uses IntX and calculates 42 in power 1048576 (which is 2^20):<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">using</span> System;
<span style="color:Blue;">using</span> System.Diagnostics;
<span style="color:Blue;">using</span> Oyster.Math;
<span style="color:Blue;">namespace</span> IntxTestApp
{
<span style="color:Blue;">class</span> Program
{
<span style="color:Blue;">static</span> <span style="color:Blue;">void</span> Calc()
{
Stopwatch sw = Stopwatch.StartNew();
IntX.Pow(42, 1 << 20);
sw.Stop();
Console.WriteLine(<span style="color:#A31515;">"{0} ms"</span>, sw.ElapsedMilliseconds);
}
<span style="color:Blue;">static</span> <span style="color:Blue;">void</span> Main()
{
Calc();
IntX.GlobalSettings.MultiplyMode = MultiplyMode.Classic;
Calc();
}
}
}
</pre></div>First Calc() call uses fast multiplication implementation (which is default), second - classic one. On my machine (Win XP Pro SP2, P4 2.8 GHz, 2 GB RAM) first call is <b>70 times</b> faster than the second one (1 second against 68 seconds). Resulting number has 1,702,101 digits; you can get it here: <a href="javascript:window.location.href='http://intx.codeplex.com/Project/Download/FileDownload.aspx?DownloadId=27428';">42pow1048576.txt</a>.<br /><br />Another example is factorial calculation:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">using</span> System;
<span style="color:Blue;">using</span> Oyster.Math;
<span style="color:Blue;">namespace</span> IntxTestApp
{
<span style="color:Blue;">class</span> Program
{
<span style="color:Blue;">static</span> IntX Factorial(IntX n)
{
<span style="color:Blue;">if</span> (n < 0)
{
<span style="color:Blue;">throw</span> <span style="color:Blue;">new</span> ArgumentException(<span style="color:#A31515;">"Can't calculate factorial for negative number."</span>, <span style="color:#A31515;">"n"</span>);
}
<span style="color:Blue;">return</span> n == 0 ? 1 : n * Factorial(n - 1);
}
<span style="color:Blue;">static</span> <span style="color:Blue;">void</span> Main()
{
Console.WriteLine(Factorial(10000));
}
}
}
</pre></div>As you can see, IntX implements all the standard arithmetic operators so its usage is transparent for developer - like if you're working with usual integer.<br /><br /><b>FHT and Calculations Precision</b><br />Internally IntX library operates with floating-point numbers when multiplication using FHT is performed so at some point it stops working correctly and loses precision. Luckily, this unpleasant side-effects effects are starting to appear when integer size is about 2^28 bytes i.e. for really huge integers. Anyway, to catch such errors I have added FHT multiplication result validity check into code - it takes N last digits of each big integer, multiplies them using classic approach and then compares last N digits of classic result with last N digits of FHT result (so it's kind of simplified CRC check). If any inconsistency is found then FhtMultiplicationException is thrown; this check can be disabled using global settings.<br /><br /><b>Future Plans</b><br />I have no plans to further develop this library - I'm just sharing it with the community.<br /><br /><b>System.Numerics.BigInteger in .NET 4.0</b><br />According to the <a href="http://blogs.msdn.com/bclteam/archive/2008/11/04/what-s-new-in-the-bcl-in-net-4-0-justin-van-patten.aspx" class="externalLink">BCL team blog<span class="externalLinkIcon"></span></a> MS is going to introduce System.Numerics.BigInteger class in .NET 4.0, this time for sure :) Once I saw this blog entity I was interested in performance of their solution - you can download preliminary version together with <a href="http://code.msdn.microsoft.com/solverfoundation" class="externalLink">MS Solver Foundation<span class="externalLinkIcon"></span></a> (it's for .NET 3.5), it's called Microsoft.SolverFoundation.Common.BigInteger in there. I did some tests and it appears that BigInteger has performance in general comparable with IntX on standard operations but starts losing when FHT comes into play (when multiplying really big integers, for example).<br /><br />So internally System.Numerics.BigInteger seems to use standard arbitrary arithmetic algorithms and I am not worrying about IntX library since, due to its use of FHT, it can be times faster for really big integers.<br /><br /><b>Comparing IntX Performance to GMP</b><br />While IntX library is fast among other libraries written for .NET it can't really compete with <a href="http://gmplib.org/" class="externalLink">The GNU MP Library<span class="externalLinkIcon"></span></a> - one of the fastest well-known Bignum libraries in the world. GNU MP (or GMP) is written in plain C and Assembly language so it compiles into optimized native code, it also uses fast calculation algorithms - that's why it's very fast. I have compared IntX performance to GMP on basic arithmetic operations and it appeared that GMP is up to 5 times faster than IntX. Actually for me it is a good result - IntX written in managed code is still quite fast :) GMP is also faster on a huge integers since, as well as IntX, it implements fast multiplication algorithm using FFT. GMP also has support for big floating-point numbers.<br /><br />So if you need to perform a lot of operations with big integers and must get the fastest possible speed from them then I'd suggest you using <a href="http://gmplib.org/" class="externalLink">GMP<span class="externalLinkIcon"></span></a> (distributed under LGPL license). However, if 5x speed loss on some operations is okay for your project and/or you don't want to include unmanaged code into your application then IntX should be enough for you.<br /><br />Btw, using GMP from C# is quite easy because there are GMP C#-wrappers available <a href="http://www.emilstefanov.net/Projects/GnuMpDotNet/" class="externalLink">here<span class="externalLinkIcon"></span></a> (this one I was using for tests) and <a href="http://gnumpnet.codeplex.com/" class="externalLink">there<span class="externalLinkIcon"></span></a>. But be careful with them - both wrappers I saw are releasing unmanaged resource they are referring (which is memory) only in Finalize() method override and not implementing IDisposable so you can end with unexpected OutOfMemoryException as I did.</div><div class="ClearBoth"></div>OysterWed, 20 Jan 2010 17:47:41 GMTUpdated Wiki: Home 20100120054741PUpdated Wiki: Homehttp://intx.codeplex.com/wikipage?version=23<div class="wikidoc"><b>Project Description</b><br />IntX is an arbitrary precision integers library written in pure C# 2.0 with fast - O(N * log N) - multiplication/division algorithms implementation. It provides all the basic operations on integers like addition, multiplication, comparing, bitwise shifting etc. It also allows parsing numbers in base from 2 to 16 and converting them to string, also in any base. The advantage of this library is fast multiplication, division and from base/to base conversion algorithms - all the fast versions of the algorithms are based on fast multiplication of big integers using Fast Hartley Transform which runs for O(N * log N * log log N) time instead of classic O(N^2).<br /><br /><b>Bits of History</b><br />I have written IntX basically because I like big numbers and had some free time. Initial implementation was standard - I was using standard big integers +, -, *, / algorithms from Khuth book. After library was written I've decided to participate in <a href="http://contest2005.gotdotnet.ru/Request/Tools/UtilitiesLib/169728.aspx" class="externalLink">contest held by GotDotNet.ru site<span class="externalLinkIcon"></span></a> and received some replies which were saying that my library is too ... usual. Well, it was true, so I've decided to implement some more interesting algorithms in it.<br /><br />I've started with writing multiplication using <a href="http://en.wikipedia.org/wiki/Discrete_Hartley_transform" class="externalLink">Fast Hartley Transform<span class="externalLinkIcon"></span></a> so big integers multiplication time estimate became to be O(N * log N * log log N) (here N is amount of DWORDs in number representation) which was a bit better then O(N^2) with classic algorithm :) Then I saw fast algorithm for transforming from one base to another in Knuth book; it was based on fast multiplication so Parse()/ToString() started working faster - O(N * (log N)^2) instead of O(N^2). Finally division was also optimized (again, with the help of fast multiplication) - became as fast as multiplication.<br /><br />All this happened in 2005 year and in 2008 I've decided to publish this library on CodePlex - maybe it will be useful for someone out there (well, there is not so many similar libraries under .NET; also System.Numeric.BigInteger from .NET FW 3.5 was cancelled). Before publishing it on CodePlex I also made some cosmetic changes in code - used new .NET 2.0 features like generics (to minimize code duplication) and rewritten unit tests to use NUnit (they were previously written for MbUnit which is almost unknown and not used by community).<br /><br /><b>Code Example</b><br />Here is the sample of code which uses IntX and calculates 42 in power 1048576 (which is 2^20):<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">using</span> System;
<span style="color:Blue;">using</span> System.Diagnostics;
<span style="color:Blue;">using</span> Oyster.Math;
<span style="color:Blue;">namespace</span> IntxTestApp
{
<span style="color:Blue;">class</span> Program
{
<span style="color:Blue;">static</span> <span style="color:Blue;">void</span> Calc()
{
Stopwatch sw = Stopwatch.StartNew();
IntX.Pow(42, 1 << 20);
sw.Stop();
Console.WriteLine(<span style="color:#A31515;">"{0} ms"</span>, sw.ElapsedMilliseconds);
}
<span style="color:Blue;">static</span> <span style="color:Blue;">void</span> Main()
{
Calc();
IntX.GlobalSettings.MultiplyMode = MultiplyMode.Classic;
Calc();
}
}
}
</pre></div>First Calc() call uses fast multiplication implementation (which is default), second - classic one. On my machine (Win XP Pro SP2, P4 2.8 GHz, 2 GB RAM) first call is <b>70 times</b> faster than the second one (1 second against 68 seconds). Resulting number has 1,702,101 digits; you can get it here: <a href="javascript:window.location.href='http://intx.codeplex.com/Project/Download/FileDownload.aspx?DownloadId=27428';">42pow1048576.txt</a>.<br /><br />Another example is factorial calculation:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">using</span> System;
<span style="color:Blue;">using</span> Oyster.Math;
<span style="color:Blue;">namespace</span> IntxTestApp
{
<span style="color:Blue;">class</span> Program
{
<span style="color:Blue;">static</span> IntX Factorial(IntX n)
{
<span style="color:Blue;">if</span> (n < 0)
{
<span style="color:Blue;">throw</span> <span style="color:Blue;">new</span> ArgumentException(<span style="color:#A31515;">"Can't calculate factorial for negative number."</span>, <span style="color:#A31515;">"n"</span>);
}
<span style="color:Blue;">return</span> n == 0 ? 1 : n * Factorial(n - 1);
}
<span style="color:Blue;">static</span> <span style="color:Blue;">void</span> Main()
{
Console.WriteLine(Factorial(10000));
}
}
}
</pre></div>As you can see, IntX implements all the standard arithmetic operators so its usage is transparent for developer - like if you're working with usual integer.<br /><br /><b>FHT and Calculations Precision</b><br />Internally IntX library operates with floating-point numbers when multiplication using FHT is performed so at some point it stops working correctly and loses precision. Luckily, this unpleasant side-effects effects are starting to appear when integer size is about 2^28 bytes i.e. for really huge integers. Anyway, to catch such errors I have added FHT multiplication result validity check into code - it takes N last digits of each big integer, multiplies them using classic approach and then compares last N digits of classic result with last N digits of FHT result (so it's kind of simplified CRC check). If any inconsistency is found then FhtMultiplicationException is thrown; this check can be disabled using global settings.<br /><br /><b>Future Plans</b><br />I have no plans to further develop this library - I'm just sharing it with the community.<br /><br /><b>System.Numerics.BigInteger in .NET 4.0</b><br />According to the <a href="http://blogs.msdn.com/bclteam/archive/2008/11/04/what-s-new-in-the-bcl-in-net-4-0-justin-van-patten.aspx" class="externalLink">BCL team blog<span class="externalLinkIcon"></span></a> MS is going to introduce System.Numerics.BigInteger class in .NET 4.0, this time for sure :) Once I saw this blog entity I was interested in performance of their solution - you can download preliminary version together with <a href="http://code.msdn.microsoft.com/solverfoundation" class="externalLink">MS Solver Foundation<span class="externalLinkIcon"></span></a> (it's for .NET 3.5), it's called Microsoft.SolverFoundation.Common.BigInteger in there. I did some tests and it appears that BigInteger has performance in general comparable with IntX on standard operations but starts losing when FHT comes into play (when multiplying really big integers, for example).<br /><br />So internally System.Numerics.BigInteger seems to use standard arbitrary arithmetic algorithms and I am not worrying about IntX library since, due to its use of FHT, it can be times faster for really big integers.<br /><br /><b>Comparing IntX Performance to GMP</b><br />While IntX library is fast among other libraries written for .NET it can't really compete with <a href="http://gmplib.org/" class="externalLink">The GNU MP Library<span class="externalLinkIcon"></span></a> - one of the fastest well-known Bignum libraries in the world. GNU MP (or GMP) is written in plain C and Assembly language so it compiles into optimized native code, it also uses fast calculation algorithms - that's why it's very fast. I have compared IntX performance to GMP on basic arithmetic operations and it appeared that GMP is up to 5 times faster than IntX. Actually for me it is a good result - IntX written in managed code is still quite fast :) GMP is also faster on a huge integers since, as well as IntX, it implements fast multiplication algorithm using FFT. GMP also has support for big floating-point numbers.<br /><br />So if you need to perform a lot of operations with big integers and must get the fastest possible speed from them then I'd suggest you using <a href="http://gmplib.org/" class="externalLink">GMP<span class="externalLinkIcon"></span></a> (distributed under LGPL license). However, if 2-10x speed loss is okay for your project and/or you don't want to include unmanaged code into your application then IntX should be enough for you.<br /><br />Btw, using GMP from C# is quite easy because there are GMP C#-wrappers available <a href="http://www.emilstefanov.net/Projects/GnuMpDotNet/" class="externalLink">here<span class="externalLinkIcon"></span></a> (this one I was using for tests) and <a href="http://gnumpnet.codeplex.com/" class="externalLink">there<span class="externalLinkIcon"></span></a>. But be careful with them - both wrappers I saw are releasing unmanaged resource they are referring (which is memory) only in Finalize() method override and not implementing IDisposable so you can end with unexpected OutOfMemoryException as I did.</div><div class="ClearBoth"></div>OysterWed, 20 Jan 2010 17:47:03 GMTUpdated Wiki: Home 20100120054703PUpdated Wiki: Homehttp://intx.codeplex.com/wikipage?version=22<div class="wikidoc"><b>Project Description</b><br />IntX is an arbitrary precision integers library written in pure C# 2.0 with fast - O(N * log N) - multiplication/division algorithms implementation. It provides all the basic operations on integers like addition, multiplication, comparing, bitwise shifting etc. It also allows parsing numbers in base from 2 to 16 and converting them to string, also in any base. The advantage of this library is fast multiplication, division and from base/to base conversion algorithms - all the fast versions of the algorithms are based on fast multiplication of big integers using Fast Hartley Transform which runs for O(N * log N * log log N) time instead of classic O(N^2).<br /><br /><b>Bits of History</b><br />I have written IntX basically because I like big numbers and had some free time. Initial implementation was standard - I was using standard big integers +, -, *, / algorithms from Khuth book. After library was written I've decided to participate in <a href="http://contest2005.gotdotnet.ru/Request/Tools/UtilitiesLib/169728.aspx" class="externalLink">contest held by GotDotNet.ru site<span class="externalLinkIcon"></span></a> and received some replies which were saying that my library is too ... usual. Well, it was true, so I've decided to implement some more interesting algorithms in it.<br /><br />I've started with writing multiplication using <a href="http://en.wikipedia.org/wiki/Discrete_Hartley_transform" class="externalLink">Fast Hartley Transform<span class="externalLinkIcon"></span></a> so big integers multiplication time estimate became to be O(N * log N * log log N) (here N is amount of DWORDs in number representation) which was a bit better then O(N^2) with classic algorithm :) Then I saw fast algorithm for transforming from one base to another in Knuth book; it was based on fast multiplication so Parse()/ToString() started working faster - O(N * (log N)^2) instead of O(N^2). Finally division was also optimized (again, with the help of fast multiplication) - became as fast as multiplication.<br /><br />All this happened in 2005 year and in 2008 I've decided to publish this library on CodePlex - maybe it will be useful for someone out there (well, there is not so many similar libraries under .NET; also System.Numeric.BigInteger from .NET FW 3.5 was cancelled). Before publishing it on CodePlex I also made some cosmetic changes in code - used new .NET 2.0 features like generics (to minimize code duplication) and rewritten unit tests to use NUnit (they were previously written for MbUnit which is almost unknown and not used by community).<br /><br /><b>Code Example</b><br />Here is the sample of code which uses IntX and calculates 42 in power 1048576 (which is 2^20):<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">using</span> System;
<span style="color:Blue;">using</span> System.Diagnostics;
<span style="color:Blue;">using</span> Oyster.Math;
<span style="color:Blue;">namespace</span> IntxTestApp
{
<span style="color:Blue;">class</span> Program
{
<span style="color:Blue;">static</span> <span style="color:Blue;">void</span> Calc()
{
Stopwatch sw = Stopwatch.StartNew();
IntX.Pow(42, 1 << 20);
sw.Stop();
Console.WriteLine(<span style="color:#A31515;">"{0} ms"</span>, sw.ElapsedMilliseconds);
}
<span style="color:Blue;">static</span> <span style="color:Blue;">void</span> Main()
{
Calc();
IntX.GlobalSettings.MultiplyMode = MultiplyMode.Classic;
Calc();
}
}
}
</pre></div>First Calc() call uses fast multiplication implementation (which is default), second - classic one. On my machine (Win XP Pro SP2, P4 2.8 GHz, 2 GB RAM) first call is <b>70 times</b> faster than the second one (1 second against 68 seconds). Resulting number has 1,702,101 digits; you can get it here: <a href="javascript:window.location.href='http://intx.codeplex.com/Project/Download/FileDownload.aspx?DownloadId=27428';">42pow1048576.txt</a>.<br /><br />Another example is factorial calculation:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">using</span> System;
<span style="color:Blue;">using</span> Oyster.Math;
<span style="color:Blue;">namespace</span> IntxTestApp
{
<span style="color:Blue;">class</span> Program
{
<span style="color:Blue;">static</span> IntX Factorial(IntX n)
{
<span style="color:Blue;">if</span> (n < 0)
{
<span style="color:Blue;">throw</span> <span style="color:Blue;">new</span> ArgumentException(<span style="color:#A31515;">"Can't calculate factorial for negative number."</span>, <span style="color:#A31515;">"n"</span>);
}
<span style="color:Blue;">return</span> n == 0 ? 1 : n * Factorial(n - 1);
}
<span style="color:Blue;">static</span> <span style="color:Blue;">void</span> Main()
{
Console.WriteLine(Factorial(10000));
}
}
}
</pre></div>As you can see, IntX implements all the standard arithmetic operators so its usage is transparent for developer - like if you're working with usual integer.<br /><br /><b>FHT and Calculations Precision</b><br />Internally IntX library operates with floating-point numbers when multiplication using FHT is performed so at some point it stops working correctly and loses precision. Luckily, this unpleasant side-effects effects are starting to appear when integer size is about 2^28 bytes i.e. for really huge integers. Anyway, to catch such errors I have added FHT multiplication result validity check into code - it takes N last digits of each big integer, multiplies them using classic approach and then compares last N digits of classic result with last N digits of FHT result (so it's kind of simplified CRC check). If any inconsistency is found then FhtMultiplicationException is thrown; this check can be disabled using global settings.<br /><br /><b>Future Plans</b><br />I have no plans to further develop this library - I'm just sharing it with the community.<br /><br /><b>System.Numerics.BigInteger in .NET 4.0</b><br />According to the <a href="http://blogs.msdn.com/bclteam/archive/2008/11/04/what-s-new-in-the-bcl-in-net-4-0-justin-van-patten.aspx" class="externalLink">BCL team blog<span class="externalLinkIcon"></span></a> MS is going to introduce System.Numerics.BigInteger class in .NET 4.0, this time for sure :) Once I saw this blog entity I was interested in performance of their solution - you can download preliminary version together with <a href="http://code.msdn.microsoft.com/solverfoundation" class="externalLink">MS Solver Foundation<span class="externalLinkIcon"></span></a> (it's for .NET 3.5), it's called Microsoft.SolverFoundation.Common.BigInteger in there. I did some tests and it appears that BigInteger has performance in general comparable with IntX on standard operations but starts losing when FHT comes into play (when multiplying really big integers, for example).<br /><br />So internally System.Numerics.BigInteger seems to use standard arbitrary arithmetic algorithms and I am not worrying about IntX library since, due to its use of FHT, it can be times faster for really big integers.<br /><br /><b>Comparing IntX Performance to GMP</b><br />While IntX library is fast among other libraries written for .NET it can't really compete with <a href="http://gmplib.org/" class="externalLink">The GNU MP Library<span class="externalLinkIcon"></span></a> - one of the fastest well-known Bignum libraries in the world. GNU MP (or GMP) is written in plain C and Assembly language so it compiles into optimized native code, it also uses fast calculation algorithms - that's why it's very fast. I have compared IntX performance to GMP on basic arithmetic operations and it appeared that <b>GMP is 2-10 times faster than IntX</b>. Actually for me it is a good result - IntX written in managed code is still quite fast :) GMP is also about 10x faster on a huge integers since, as well as IntX, it implements fast multiplication algorithm using FFT. GMP also has support for big floating-point numbers.<br /><br />So if you need to perform a lot of operations with big integers and must get the fastest possible speed from them then I'd suggest you using <a href="http://gmplib.org/" class="externalLink">GMP<span class="externalLinkIcon"></span></a> (distributed under LGPL license). However, if 2-10x speed loss is okay for your project and/or you don't want to include unmanaged code into your application then IntX should be enough for you.<br /><br />Btw, using GMP from C# is quite easy because there are GMP C#-wrappers available <a href="http://www.emilstefanov.net/Projects/GnuMpDotNet/" class="externalLink">here<span class="externalLinkIcon"></span></a> (this one I was using for tests) and <a href="http://gnumpnet.codeplex.com/" class="externalLink">there<span class="externalLinkIcon"></span></a>. But be careful with them - both wrappers I saw are releasing unmanaged resource they are referring (which is memory) only in Finalize() method override and not implementing IDisposable so you can end with unexpected OutOfMemoryException as I did.</div><div class="ClearBoth"></div>OysterWed, 20 Jan 2010 17:43:33 GMTUpdated Wiki: Home 20100120054333PUpdated Wiki: Homehttp://intx.codeplex.com/wikipage?version=21<div class="wikidoc"><b>Project Description</b><br />IntX is an arbitrary precision integers library written in pure C# 2.0 with fast - O(N * log N) - multiplication/division algorithms implementation. It provides all the basic operations on integers like addition, multiplication, comparing, bitwise shifting etc. It also allows parsing numbers in base from 2 to 16 and converting them to string, also in any base. The advantage of this library is fast multiplication, division and from base/to base conversion algorithms - all the fast versions of the algorithms are based on fast multiplication of big integers using Fast Hartley Transform which runs for O(N * log N * log log N) time instead of classic O(N^2).<br /><br /><b>Bits of History</b><br />I have written IntX basically because I like big numbers and had some free time. Initial implementation was standard - I was using standard big integers +, -, *, / algorithms from Khuth book. After library was written I've decided to participate in <a href="http://contest2005.gotdotnet.ru/Request/Tools/UtilitiesLib/169728.aspx" class="externalLink">contest held by GotDotNet.ru site<span class="externalLinkIcon"></span></a> and received some replies which were saying that my library is too ... usual. Well, it was true, so I've decided to implement some more interesting algorithms in it.<br /><br />I've started with writing multiplication using <a href="http://en.wikipedia.org/wiki/Discrete_Hartley_transform" class="externalLink">Fast Hartley Transform<span class="externalLinkIcon"></span></a> so big integers multiplication time estimate became to be O(N * log N * log log N) (here N is amount of DWORDs in number representation) which was a bit better then O(N^2) with classic algorithm :) Then I saw fast algorithm for transforming from one base to another in Knuth book; it was based on fast multiplication so Parse()/ToString() started working faster - O(N * (log N)^2) instead of O(N^2). Finally division was also optimized (again, with the help of fast multiplication) - became as fast as multiplication.<br /><br />All this happened in 2005 year and in 2008 I've decided to publish this library on CodePlex - maybe it will be useful for someone out there (well, there is not so many similar libraries under .NET; also System.Numeric.BigInteger from .NET FW 3.5 was cancelled). Before publishing it on CodePlex I also made some cosmetic changes in code - used new .NET 2.0 features like generics (to minimize code duplication) and rewritten unit tests to use NUnit (they were previously written for MbUnit which is almost unknown and not used by community).<br /><br /><b>Code Example</b><br />Here is the sample of code which uses IntX and calculates 42 in power 1048576 (which is 2^20):<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">using</span> System;
<span style="color:Blue;">using</span> System.Diagnostics;
<span style="color:Blue;">using</span> Oyster.Math;
<span style="color:Blue;">namespace</span> IntxTestApp
{
<span style="color:Blue;">class</span> Program
{
<span style="color:Blue;">static</span> <span style="color:Blue;">void</span> Calc()
{
Stopwatch sw = Stopwatch.StartNew();
IntX.Pow(42, 1 << 20);
sw.Stop();
Console.WriteLine(<span style="color:#A31515;">"{0} ms"</span>, sw.ElapsedMilliseconds);
}
<span style="color:Blue;">static</span> <span style="color:Blue;">void</span> Main()
{
Calc();
IntX.GlobalSettings.MultiplyMode = MultiplyMode.Classic;
Calc();
}
}
}
</pre></div>First Calc() call uses fast multiplication implementation (which is default), second - classic one. On my machine (Win XP Pro SP2, P4 2.8 GHz, 2 GB RAM) first call is <b>70 times</b> faster than the second one (1 second against 68 seconds). Resulting number has 1,702,101 digits; you can get it here: <a href="javascript:window.location.href='http://intx.codeplex.com/Project/Download/FileDownload.aspx?DownloadId=27428';">42pow1048576.txt</a>.<br /><br />Another example is factorial calculation:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">using</span> System;
<span style="color:Blue;">using</span> Oyster.Math;
<span style="color:Blue;">namespace</span> IntxTestApp
{
<span style="color:Blue;">class</span> Program
{
<span style="color:Blue;">static</span> IntX Factorial(IntX n)
{
<span style="color:Blue;">if</span> (n < 0)
{
<span style="color:Blue;">throw</span> <span style="color:Blue;">new</span> ArgumentException(<span style="color:#A31515;">"Can't calculate factorial for negative number."</span>, <span style="color:#A31515;">"n"</span>);
}
<span style="color:Blue;">return</span> n == 0 ? 1 : n * Factorial(n - 1);
}
<span style="color:Blue;">static</span> <span style="color:Blue;">void</span> Main()
{
Console.WriteLine(Factorial(10000));
}
}
}
</pre></div>As you can see, IntX implements all the standard arithmetic operators so its usage is transparent for developer - like if you're working with usual integer.<br /><br /><b>FHT and Calculations Precision</b><br />Internally IntX library operates with floating-point numbers when multiplication using FHT is performed so at some point it stops working correctly and loses precision. Luckily, this unpleasant side-effects effects are starting to appear when integer size is about 2^28 bytes i.e. for really huge integers. Anyway, to catch such errors I have added FHT multiplication result validity check into code - it takes N last digits of each big integer, multiplies them using classic approach and then compares last N digits of classic result with last N digits of FHT result (so it's kind of simplified CRC check). If any inconsistency is found then FhtMultiplicationException is thrown; this check can be disabled using global settings.<br /><br /><b>Future Plans</b><br />I have no plans to further develop this library - I'm just sharing it with the community.<br /><br /><b>System.Numerics.BigInteger in .NET 4.0</b><br />According to the <a href="http://blogs.msdn.com/bclteam/archive/2008/11/04/what-s-new-in-the-bcl-in-net-4-0-justin-van-patten.aspx" class="externalLink">BCL team blog<span class="externalLinkIcon"></span></a> MS is going to introduce System.Numerics.BigInteger class in .NET 4.0, this time for sure :) Once I saw this blog entity I was interested in performance of their solution - you can download preliminary version together with <a href="http://code.msdn.microsoft.com/solverfoundation" class="externalLink">MS Solver Foundation<span class="externalLinkIcon"></span></a> (it's for .NET 3.5), it's called Microsoft.SolverFoundation.Common.BigInteger in there. I did some tests and it appears that BigInteger has performance in general comparable with IntX on standard operations but starts losing when FHT comes into play (when multiplying really big integers, for example).<br /><br />So internally System.Numerics.BigInteger seems to use standard arbitrary arithmetic algorithms and I am not worrying about IntX library since, due to its use of FHT, it can be times faster for really big integers.<br /><br /><b>Comparing IntX Performance to GMP</b><br />While IntX library is fast among other libraries written for .NET it can't really compete with <a href="http://gmplib.org/" class="externalLink">The GNU MP Library<span class="externalLinkIcon"></span></a> - one of the fastest well-known Bignum libraries in the world. GNU MP (or GMP) is written in plain C and Assembly language so it compiles into optimized native code, it also uses fast calculation algorithms - that's why it's very fast. I have compared IntX performance to GMP on basic arithmetic operations and it appeared that <b>GMP is 2-10 times faster than IntX</b>. Actually for me it is a good result - IntX written in managed code is still quite fast :) GMP is also about 10x faster on a huge integers since, as well as IntX, it implements fast multiplication algorithm using FFT. GMP also has support for big floating-point numbers.<br /><br />So if you need to perform a lot of operations with big integers and must get the fastest possible speed from them then I'd suggest you using <a href="http://gmplib.org/" class="externalLink">GMP<span class="externalLinkIcon"></span></a> (distributed under LGPL license). However, if 2-10x speed loss is okay for your project and/or you don't want to include unmanaged code into your application then IntX should be enough for you.<br /><br />Btw, using GMP from C# is quite easy because there are GMP C#-wrappers available <a href="http://www.emilstefanov.net/Projects/GnuMpDotNet/" class="externalLink">here<span class="externalLinkIcon"></span></a> (this one I was using for tests) and <a href="http://gnumpnet.codeplex.com/" class="externalLink">there<span class="externalLinkIcon"></span></a>. But be careful with them - both wrappers I saw are releasing unmanaged resource the are referring (which is memory) only in Finalize() method override and not implementing IDisposable so you can end with unexpected OutOfMemoryException as I did.</div><div class="ClearBoth"></div>OysterWed, 20 Jan 2010 17:42:49 GMTUpdated Wiki: Home 20100120054249PUpdated Wiki: Homehttp://intx.codeplex.com/wikipage?version=20<div class="wikidoc"><b>Project Description</b><br />IntX is an arbitrary precision integers library written in pure C# 2.0 with fast - O(N * log N) - multiplication/division algorithms implementation. It provides all the basic operations on integers like addition, multiplication, comparing, bitwise shifting etc. It also allows parsing numbers in base from 2 to 16 and converting them to string, also in any base. The advantage of this library is fast multiplication, division and from base/to base conversion algorithms - all the fast versions of the algorithms are based on fast multiplication of big integers using Fast Hartley Transform which runs for O(N * log N * log log N) time instead of classic O(N^2).<br /><br /><b>Bits of History</b><br />I have written IntX basically because I like big numbers and had some free time. Initial implementation was standard - I was using standard big integers +, -, *, / algorithms from Khuth book. After library was written I've decided to participate in <a href="http://contest2005.gotdotnet.ru/Request/Tools/UtilitiesLib/169728.aspx" class="externalLink">contest held by GotDotNet.ru site<span class="externalLinkIcon"></span></a> and received some replies which were saying that my library is too ... usual. Well, it was true, so I've decided to implement some more interesting algorithms in it.<br /><br />I've started with writing multiplication using <a href="http://en.wikipedia.org/wiki/Discrete_Hartley_transform" class="externalLink">Fast Hartley Transform<span class="externalLinkIcon"></span></a> so big integers multiplication time estimate became to be O(N * log N * log log N) (here N is amount of DWORDs in number representation) which was a bit better then O(N^2) with classic algorithm :) Then I saw fast algorithm for transforming from one base to another in Knuth book; it was based on fast multiplication so Parse()/ToString() started working faster - O(N * (log N)^2) instead of O(N^2). Finally division was also optimized (again, with the help of fast multiplication) - became as fast as multiplication.<br /><br />All this happened in 2005 year and in 2008 I've decided to publish this library on CodePlex - maybe it will be useful for someone out there (well, there is not so many similar libraries under .NET; also System.Numeric.BigInteger from .NET FW 3.5 was cancelled). Before publishing it on CodePlex I also made some cosmetic changes in code - used new .NET 2.0 features like generics (to minimize code duplication) and rewritten unit tests to use NUnit (they were previously written for MbUnit which is almost unknown and not used by community).<br /><br /><b>Code Example</b><br />Here is the sample of code which uses IntX and calculates 42 in power 1048576 (which is 2^20):<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">using</span> System;
<span style="color:Blue;">using</span> System.Diagnostics;
<span style="color:Blue;">using</span> Oyster.Math;
<span style="color:Blue;">namespace</span> IntxTestApp
{
<span style="color:Blue;">class</span> Program
{
<span style="color:Blue;">static</span> <span style="color:Blue;">void</span> Calc()
{
Stopwatch sw = Stopwatch.StartNew();
IntX.Pow(42, 1 << 20);
sw.Stop();
Console.WriteLine(<span style="color:#A31515;">"{0} ms"</span>, sw.ElapsedMilliseconds);
}
<span style="color:Blue;">static</span> <span style="color:Blue;">void</span> Main()
{
Calc();
IntX.GlobalSettings.MultiplyMode = MultiplyMode.Classic;
Calc();
}
}
}
</pre></div>First Calc() call uses fast multiplication implementation (which is default), second - classic one. On my machine (Win XP Pro SP2, P4 2.8 GHz, 2 GB RAM) first call is <b>70 times</b> faster than the second one (1 second against 68 seconds). Resulting number has 1,702,101 digits; you can get it here: <a href="javascript:window.location.href='http://intx.codeplex.com/Project/Download/FileDownload.aspx?DownloadId=27428';">42pow1048576.txt</a>.<br /><br />Another example is factorial calculation:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">using</span> System;
<span style="color:Blue;">using</span> Oyster.Math;
<span style="color:Blue;">namespace</span> IntxTestApp
{
<span style="color:Blue;">class</span> Program
{
<span style="color:Blue;">static</span> IntX Factorial(IntX n)
{
<span style="color:Blue;">if</span> (n < 0)
{
<span style="color:Blue;">throw</span> <span style="color:Blue;">new</span> ArgumentException(<span style="color:#A31515;">"Can't calculate factorial for negative number."</span>, <span style="color:#A31515;">"n"</span>);
}
<span style="color:Blue;">return</span> n == 0 ? 1 : n * Factorial(n - 1);
}
<span style="color:Blue;">static</span> <span style="color:Blue;">void</span> Main()
{
Console.WriteLine(Factorial(10000));
}
}
}
</pre></div>As you can see, IntX implements all the standard arithmetic operators so its usage is transparent for developer - like if you're working with usual integer.<br /><br /><b>FHT and Calculations Precision</b><br />Internally IntX library operates with floating-point numbers when multiplication using FHT is performed so at some point it stops working correctly and loses precision. Luckily, this unpleasant side-effects effects are starting to appear when integer size is about 2^28 bytes i.e. for really huge integers. Anyway, to catch such errors I have added FHT multiplication result validity check into code - it takes N last digits of each big integer, multiplies them using classic approach and then compares last N digits of classic result with last N digits of FHT result (so it's kind of simplified CRC check). If any inconsistency is found then FhtMultiplicationException is thrown; this check can be disabled using global settings.<br /><br /><b>Future Plans</b><br />I have no plans to further develop this library - I'm just sharing it with the community.<br /><br /><b>System.Numerics.BigInteger in .NET 4.0</b><br />According to the <a href="http://blogs.msdn.com/bclteam/archive/2008/11/04/what-s-new-in-the-bcl-in-net-4-0-justin-van-patten.aspx" class="externalLink">BCL team blog<span class="externalLinkIcon"></span></a> MS is going to introduce System.Numerics.BigInteger class in .NET 4.0, this time for sure :) Once I saw this blog entity I was interested in performance of their solution - you can download preliminary version together with <a href="http://code.msdn.microsoft.com/solverfoundation" class="externalLink">MS Solver Foundation<span class="externalLinkIcon"></span></a> (it's for .NET 3.5), it's called Microsoft.SolverFoundation.Common.BigInteger in there. I did some tests and it appears that BigInteger has performance in general comparable with IntX on standard operations but starts losing when FHT comes into play (when multiplying really big integers, for example).<br /><br />So internally System.Numerics.BigInteger seems to use standard arbitrary arithmetic algorithms and I am not worrying about IntX library since, due to its use of FHT, it can be times faster for really big integers.<br /><br /><b>Comparing IntX Performance to GMP</b><br />While IntX library is fast among other libraries written for .NET it can't really compete with <a href="http://gmplib.org/" class="externalLink">The GNU MP Library<span class="externalLinkIcon"></span></a> - one of the fastest well-known Bignum libraries in the world. GNU MP (or GMP) is written in plain C and Assembly language so it compiles into optimized native code, it also uses fast calculation algorithms - that's why it's very fast. I have compared IntX performance to GMP on basic arithmetic operations and it appeared that <b>GMP is 2-10 times faster than IntX</b>. Actually for me it is a good result - IntX written in managed code is still quite fast :) GMP is also about 10x faster on a huge integers since, as well as IntX, it implements fast multiplication algorithm using FFT. GMP also has support for big floating-point numbers.<br /><br />So if you need to perform a lot of operations with big integers and must get the fastest possible speed from them then I'd suggest you using <a href="http://gmplib.org/" class="externalLink">GMP<span class="externalLinkIcon"></span></a> (distributed under LGPL license). However, if 2-10x speed loss is okay for your project and/or you don't want to include unmanaged code into your application then IntX should be enough for you. Btw, using GMP from C# is quite easy because there are GMP C#-wrappers available <a href="http://www.emilstefanov.net/Projects/GnuMpDotNet/" class="externalLink">here<span class="externalLinkIcon"></span></a> (this one I was using for tests) and <a href="http://gnumpnet.codeplex.com/" class="externalLink">there<span class="externalLinkIcon"></span></a> and maybe somewhere else as well :)</div><div class="ClearBoth"></div>OysterWed, 20 Jan 2010 17:28:33 GMTUpdated Wiki: Home 20100120052833P