Alternative to BigInteger.ModPow(); in C#

2020-06-30 04:09发布

问题:

i'm looking for an alternative to the BigInteger package of C# which has been introduced with NET 4.x.

The mathematical operations with this object are terribly slow, I guess this is caused by the fact that the arithmetics are done on a higher level than the primitive types - or badly optimized, whatever.

Int64/long/ulong or other 64bit-numbers are way to small and won't calculate correctly - I'm talking about 64bit-integer to the power of 64-bit integers.

Hopefully someone can suggest my something. Thanks in advance.

回答1:

Honestly, if you have extremely large numbers and need to do heavy computations with them and the BigInteger library still isn't cutting it for you, why not offload it onto an external process using whatever language or toolkit you know of that does it best? Are you truly constrained to write whatever it is you're trying to accomplish entirely in C#?

For example, you can offload to MATLAB in C#.



回答2:

BIGInteger is indeed very slow. One of the reasons is it's immutability.

If you do a = a - b you will get a new copy of a. Normally this is fast. With BigInteger and say an integer of 2048 bits it will need to allocate an extra 2KB.

It should also have different multiplication-algorithms depending on integersize (I assume it is not that sophisticated). What I mean is that for very very large integers a different algorithm using fourier transforms works best and for smaller integers you break the work down in smaller multiplies (divide and conquer approach). See more on http://en.wikipedia.org/wiki/Multiplication_algorithm

Either way there are alternatives, none of which I have used or tested. They might be slower as .NET internal for all I know. (making a testcase and do some valid testing is your friend)

  • Google 'C# large integer multiplication' for a lot of homemade BigInteger implementations (usually from pre C#4.0 when BIGInteger was introduced)

  • https://github.com/devoyster/IntXLib

  • http://gmplib.org/ (there are C# wrappers)

  • http://www.extremeoptimization.com/ (commercial)

  • http://mathnetnumerics.codeplex.com/ (nice opensource, but not much onboard for very large integers)



回答3:

public static int PowerBySquaring(int baseNumber, int exponent)
{
int result = 1;
while (exponent != 0)
{
if ((exponent & 1)==1)
{
result *= baseNumber;
}
exponent >>= 1;
baseNumber *= baseNumber;
}

return result;
}