I am writing a class which needs accurate division of the BigInteger class in C#.
Example:
BigInteger x = BigInteger.Parse(\"10000000000000000000000
In the above example, the numbers are still small enough to be converted to double
, so in this case you can say
double result = (double)x / (double)y;
If x
and y
are too huge for a double
but still comparable, maybe this great trick is helpful:
double result = Math.Exp(BigInteger.Log(x) - BigInteger.Log(y));
But in general, when the BigInteger
are huge, and their quotient is huge too, this is hard to do without importing a third-party library.
Parse it to double:
double a = Convert.ToDouble(x);
double b = Convert.ToDouble(y);
Console.WriteLine(a / b);
If you need to keep full precision, use an implementation of rationals (the Java equivalent would be the Fraction class from Apache Commons Math library). There are various implementations lurking around, but the most light weight solution for .NET 4.0 (as it has System.Numerics.BigInteger built in) would be the following:
System.Numerics.BigInteger x = System.Numerics.BigInteger.Parse("10000000000000000000000000000000000000000000000000000");
System.Numerics.BigInteger y = System.Numerics.BigInteger.Parse("20000000000000000000000000000000000000000000000000000");
// From BigRationalLibrary
Numerics.BigRational r = new Numerics.BigRational(x,y);
Console.Out.WriteLine(r.ToString());
// outputs "1/2", but can be converted to floating point if needed.
To get this to work you need the System.Numberics.BigInteger from .Net 4.0 System.Numerics.dll and the BigRational implementation from CodePlex.
There is a Rational structure implemented in the Microsoft Solver Foundation 3.0 too. At the time of writing, the www.solverfoundation.com site was broken, thus a link to the archive.
As you might know division of integers will not produce decimal values so your result is truncated to 0. According to this question big double implementation can be found here, but last release of it was in 2009. If you look further you might find newer one or this one is simply finished.
Sound like a job for Fixed Point (rather than floating point).
Simply pre-shift the numerator by the number of fractional bits you need, like this:
BigInteger quotient = (x << 10) / y;
That would give you 10 bits after the dot (approximately 3 decimal digits).
What accuracy you need for the division? One way would be:
double
and divide by 1000The same in code:
BigInteger x = BigInteger.Parse("1000000000000000000000000000000000000000000000000000000000000000000000000000000000000");
BigInteger y = BigInteger.Parse("2000000000000000000000000000000000000000000000000000000000000000000000000000000000000");
x *= 1000;
x /= y;
double result = (double)x;
result /= 1000;
Console.WriteLine(result);