從Codeplex獲得BigRational。它是微軟的Base Class Library的一部分,因此它是.Net的一項工作。一旦你的,然後做一些事情,如:
System.Numerics.BigInteger x = GetDividend() ;
System.Numerics.BigInteger y = GetDivisor() ;
BigRational r = new BigRational(x , y) ;
double value = (double) r ;
與必然溢/下溢/的精度,當然,另一個問題損失的處理。
既然你不能在BigRational庫拖放到你的代碼,顯然,其他的辦法是走出right algorithms book並推出自己的...
最簡單的方法,當然,滾動」自己的「,因爲有理數表示爲兩個整數的比率(除法),是從BigRational類抓取顯式轉換爲雙運算符並調整它以適應。我花了大約15分鐘。
關於我所做的唯一重大修改是當結果爲正數或負數零/無窮時,結果的符號如何設置。當我在它時,我將它轉換爲BigInteger
擴展方法爲您:
public static class BigIntExtensions
{
public static double DivideAndReturnDouble(this BigInteger x , BigInteger y)
{
// The Double value type represents a double-precision 64-bit number with
// values ranging from -1.79769313486232e308 to +1.79769313486232e308
// values that do not fit into this range are returned as +/-Infinity
if (SafeCastToDouble(x) && SafeCastToDouble(y))
{
return (Double) x/(Double) y;
}
// kick it old-school and figure out the sign of the result
bool isNegativeResult = ((x.Sign < 0 && y.Sign > 0) || (x.Sign > 0 && y.Sign < 0)) ;
// scale the numerator to preseve the fraction part through the integer division
BigInteger denormalized = (x * s_bnDoublePrecision)/y ;
if (denormalized.IsZero)
{
return isNegativeResult ? BitConverter.Int64BitsToDouble(unchecked((long)0x8000000000000000)) : 0d; // underflow to -+0
}
Double result = 0 ;
bool isDouble = false ;
int scale = DoubleMaxScale ;
while (scale > 0)
{
if (!isDouble)
{
if (SafeCastToDouble(denormalized))
{
result = (Double) denormalized;
isDouble = true;
}
else
{
denormalized = denormalized/10 ;
}
}
result = result/10 ;
scale-- ;
}
if (!isDouble)
{
return isNegativeResult ? Double.NegativeInfinity : Double.PositiveInfinity;
}
else
{
return result;
}
}
private const int DoubleMaxScale = 308 ;
private static readonly BigInteger s_bnDoublePrecision = BigInteger.Pow(10 , DoubleMaxScale) ;
private static readonly BigInteger s_bnDoubleMaxValue = (BigInteger) Double.MaxValue;
private static readonly BigInteger s_bnDoubleMinValue = (BigInteger) Double.MinValue;
private static bool SafeCastToDouble(BigInteger value)
{
return s_bnDoubleMinValue <= value && value <= s_bnDoubleMaxValue;
}
}
您需要它有多精確? – 2012-08-08 20:14:48
你正在處理的數字是什麼。請顯示數字的性質。 – MethodMan 2012-08-08 20:16:13
@AustinSalonen:精度越高越好,但即使精確到幾位十進制數字也足以達到我想要的位置。 – 2012-08-08 20:20:11