What is the equivalent of bigint in C#?
That corresponds to the long (or Int64), a 64-bit integer.
Although if the number from the database happens to be small enough, and you accidentally use an Int32, etc., you'll be fine. But the Int64 will definitely hold it.
And the error you get if you use something smaller and the full size is needed? A stack overflow! Yay!
Big integers in C#
As of .NET 4.0 you can use the System.Numerics.BigInteger class. See documentation here: http://msdn.microsoft.com/en-us/library/system.numerics.biginteger(v=vs.110).aspx
Another alternative is the IntX class.
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.
Handling Big Integers in C#
If you're only looking at the last four digits, you don't need anything larger than an integer. Consider this:
When multiplying two numbers, if you are only interested in the least significant digits (i.e. the last four digits), then the upper-most digits will not have an effect on lowest digits of the outcome... so you can just "throw out" the most significant (right-side) digits before you multiply.
For example: I want to multiply two large numbers but I only need the last two digits:
int num1 = 123456789;
int num2 = 987654321;
int result = num1 * num2; // Last two digits would be "69" but this OVERFLOWS
but if we multiply only the last two digits...
int result = (num1 % 100) * (num2 % 100); // result = 89 * 21
89 * 21 = 1869 (the last two digits are still "69" but we have not overflowed).
I used this technique to calculate the Six Right-Most Digits of 1,000,000 factorial.
How to compare big integers stored in int array?
OK, let's implement the comparisons; the typical way uses universal comparison (in some languages it's even has a special operator <=>
)
class HugeInteger {
...
// Universal comparator
// +1 left > right
// 0 left == right
// -1 left < right
public static int Compare(HugeInteger left, HugeInteger right) {
// first, we should deal with null's; let null be the leaset possible value
// left and right are just the references of one inctance?
if (Object.ReferenceEquals(left, right))
return 0;
else if (left == null)
return -1;
else if (right == null)
return 1;
// Now we checked for null, let's compare both arrays
//DONE: no 39, 40 or other magic numbers, but Length
for (int i = 0; i < left.array.Length; ++i)
if (left.array[i] < right.array[i])
return -1;
else if (left.array[i] > right.array[i])
return 1;
return 0; // no differences found, so left equals to right
}
Having comparator implemented it's very easy to write isLessThan
, isGreaterThan
:
public bool isLessThan(HugeInteger other) {
return Compare(this, other) < 0;
}
public bool isGreaterThan(HugeInteger other) {
return Compare(this, other) > 0;
}
....
How can I use bigint with C#?
You can use System.Numerics.BigInteger
(add a reference to System.Numerics assembly). As mentioned in the comments this might not be the right approach though.
Why am I getting a system overflow using big integer (System.Numerics)?
BigInteger decodedMessage = new BigInteger(Math.Pow(code, d) % pq);
Well, Math.Pow(code, d) % pq
is not a BigInteger, it's an expression of type double
. Converting the result to a BigInteger won't have an effect until the computation is complete (and has overflowed).
Math.Pow
can easily overflow to Double.PositiveInfinity
with large numbers, and Double.PositiveInfinity % someNumber
yields Double.NaN
. Calling new BigInteger(Double.NaN)
yields the error you have described.
You need to do the computation in BigInteger. Fortunately, there's a method for exactly that purpose (BigInteger.ModPow):
BigInteger decodedMessage = BigInteger.ModPow(code, d, pq);
(BigInteger.ModPow requires BigInteger parameters, but there are implicit conversions from int to BigInteger.)
multiply very big integer in .NET
You need to use BigInteger.Parse
.
BigInteger num = BigInteger.Parse("1253999939979969998746");
If you try to use an integer value like below
BigInteger num = 1253999939979969998746;
the right hand side needs to have a type, which by default will be an Int32
or a long
. But since the number is too large to be an Int32
or a long
, the conversion fails, hence the error you get.
As Tim Schmelter pointed out in a comment, to then do your multiplication, you can do the following:
BigInteger num = BigInteger.Multiply(BigInteger.Parse("1253999939979969998746"),
BigInteger.Parse("9999999999"));
Related Topics
What's the Difference Between Task.Start/Wait and Async/Await
Efficient Way to Remove All Whitespace from String
Copy File(S) from One Project to Another Using Post Build Event...Vs2010
Detecting Usb Drive Insertion and Removal Using Windows Service and C#
How Does the C# Compiler Detect Com Types
Stataskscheduler and Sta Thread Message Pumping
Entity Framework (Ef) Code First Cascade Delete for One-To-Zero-Or-One Relationship
Httpwebrequest Using Basic Authentication
How to Find the Most Recent File in a Directory Using .Net, and Without Looping
Wpf Binding UI Events to Commands in Viewmodel
"The Remote Certificate Is Invalid According to the Validation Procedure." Using Gmail Smtp Server
What Guarantees Are There on the Run-Time Complexity (Big-O) of Linq Methods
How Do Foreach Loops Work in C#
ASP.NET MVC Binding to a Dictionary
How to Access Session Variables from Any Class in ASP.NET
Quickest Way to Compare Two Generic Lists for Differences