[英]BigInteger division in C#
I am writing a class which needs accurate division of the BigInteger class in C#. 我正在编写一个需要在C#中精确划分BigInteger类的类。
Example: 例:
BigInteger x = BigInteger.Parse("1000000000000000000000000000000000000000000000000000000000000000000000000000000000000");
BigInteger y = BigInteger.Parse("2000000000000000000000000000000000000000000000000000000000000000000000000000000000000");
x /= y;
Console.WriteLine(x.ToString());
//Output = 0
The problem is that being an Integer, naturally it does not hold decimal values. 问题是作为整数,它自然不包含十进制值。 How can I overcome this to get the real result of 0.5 (given example).
我如何克服这个问题以获得0.5的真实结果(给出示例)。
PS The solution must be able to accurately divide any BigInteger, not just the example! PS该解决方案必须能够准确地划分所有BigInteger,而不仅仅是示例!
In the above example, the numbers are still small enough to be converted to double
, so in this case you can say 在上面的示例中,数字仍然很小,可以转换为
double
,因此在这种情况下,您可以说
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: 如果
x
和y
对于double
y
太大了,但仍然可比,那么这个好技巧可能会有所帮助:
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. 但是总的来说,当
BigInteger
很大且它们的商也很大时,如果不导入第三方库就很难做到这一点。
What accuracy you need for the division? 您需要什么精度划分? One way would be:
一种方法是:
double
and divide by 1000 double
并除以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);
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). 如果需要保持完全的精度,请使用合理性的实现(Java等效项是Apache Commons Math库中的Fraction类)。 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:
潜伏着各种各样的实现,但是.NET 4.0(因为它内置了System.Numerics.BigInteger)最轻便的解决方案如下:
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. 若要使其正常工作,您需要.Net 4.0 System.Numerics.dll中的System.Numberics.BigInteger和CodePlex中的BigRational实现。
There is a Rational structure implemented in the Microsoft Solver Foundation 3.0 too. 在Microsoft Solver Foundation 3.0中也实现了Rational结构 。 At the time of writing, the www.solverfoundation.com site was broken, thus a link to the archive.
在撰写本文时,www.solverfoundation.com网站已损坏,因此指向档案的链接。
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). 这将为您提供点后的10位(大约3个十进制数字)。
//b = 10x bigger as a => fraction should be 0.1
BigInteger a = BigInteger.Pow(10, 5000);
BigInteger b = BigInteger.Pow(10, 5001);
//before the division, multiple by a 1000 for a precision of 3, afterwards
//divide the result by this.
var fraction = (double) BigInteger.Divide(a * 1000, b) / 1000;
Parse it to double: 将其解析为两倍:
double a = Convert.ToDouble(x);
double b = Convert.ToDouble(y);
Console.WriteLine(a / b);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.