BigInteger division in C#

后端 未结 7 1524
礼貌的吻别
礼貌的吻别 2020-12-09 19:05

I am writing a class which needs accurate division of the BigInteger class in C#.

Example:

BigInteger x = BigInteger.Parse(\"10000000000000000000000         


        
相关标签:
7条回答
  • 2020-12-09 19:43

    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.

    0 讨论(0)
  • 2020-12-09 19:43

    Parse it to double:

    double a = Convert.ToDouble(x);
    double b = Convert.ToDouble(y);
    
    Console.WriteLine(a / b);
    
    0 讨论(0)
  • 2020-12-09 19:44

    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.

    0 讨论(0)
  • 2020-12-09 19:46

    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.

    0 讨论(0)
  • 2020-12-09 19:49

    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).

    0 讨论(0)
  • 2020-12-09 19:50

    What accuracy you need for the division? One way would be:

    • Multiply the numerator by, say, 1000
    • Divide the numbers
    • Convert the result to double and divide by 1000

    The 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);
    
    0 讨论(0)
提交回复
热议问题