我正在编写一个需要在C#中精确划分BigInteger类的类。
示例:
BigInteger x = BigInteger.Parse("1000000000000000000000000000000000000000000000000000000000000000000000000000000000000");
BigInteger y = BigInteger.Parse("2000000000000000000000000000000000000000000000000000000000000000000000000000000000000");
x /= y;
Console.WriteLine(x.ToString());
//Output = 0
问题是作为一个整数,自然它不包含十进制值。 如何克服这一点以获得0.5的实际结果(给出示例)。
P.S。解决方案必须能够准确地划分任何BigInteger,而不仅仅是示例!
答案 0 :(得分:15)
在上面的例子中,数字仍然很小,可以转换为double
,所以在这种情况下你可以说
double result = (double)x / (double)y;
如果x
和y
对于double
来说太大了但仍具有可比性,那么这个很棒的技巧可能会有所帮助:
double result = Math.Exp(BigInteger.Log(x) - BigInteger.Log(y));
但总的来说,当BigInteger
很大,而且它们的商数也很大时,如果不导入第三方库,这很难做到。
答案 1 :(得分:6)
分部需要什么准确度?一种方法是:
double
并除以1000 代码相同:
BigInteger x = BigInteger.Parse("1000000000000000000000000000000000000000000000000000000000000000000000000000000000000");
BigInteger y = BigInteger.Parse("2000000000000000000000000000000000000000000000000000000000000000000000000000000000000");
x *= 1000;
x /= y;
double result = (double)x;
result /= 1000;
Console.WriteLine(result);
答案 2 :(得分:1)
如果需要保持完全精确,请使用有理数的实现(Java等效项将是Apache Commons Math库中的Fraction类)。有各种各样的实现潜伏,但.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.
要使其工作,您需要来自.Net 4.0 System.Numerics.dll的System.Numberics.BigInteger和CodePlex的BigRational实现。
Rational structure也实施了Microsoft Solver Foundation 3.0。在撰写本文时,www.solverfoundation.com网站被破坏,因此链接到存档。
答案 3 :(得分:0)
你可能知道整数除法不会产生十进制值,所以你的结果被截断为0.根据this question可以找到大的双重实现here,但它的最后一个版本是在2009年如果你看得更远,你可能会找到更新的或者这个简单完成。
答案 4 :(得分:0)
听起来像Fixed Point的工作(而不是浮点)。
只需将分子预先移位所需的小数位数,如下所示:
BigInteger quotient = (x << 10) / y;
这将在点之后给出10位(大约3位小数)。
答案 5 :(得分:0)
//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;
答案 6 :(得分:0)
我找到了一个纯BigInteger版本:
static BigInteger FlooredIntDiv(BigInteger a, BigInteger b)
{
if (a < 0)
{
if (b > 0)
return (a - b + 1) / b;
}
else if (a > 0)
{
if (b < 0)
return (a - b - 1) / b;
}
return a / b;
}
源(用于长型): Floored integer division
答案 7 :(得分:-1)
解析它加倍:
double a = Convert.ToDouble(x);
double b = Convert.ToDouble(y);
Console.WriteLine(a / b);