おそらくあなたはBigRationalを探していますか?Microsoftは、CodePlexのBCLプロジェクトでリリースしました。実際にどのように、またはそれがあなたのニーズに合うかどうかはわかりません。
有理数として保持します。キャストまたは乗算のいずれかによって、10進値の文字列を取得できます。
var r = new BigRational(5000, 3768);
Console.WriteLine((decimal)r);
Console.WriteLine((double)r);
または、次のような単純な(ish)拡張メソッドを使用します。
public static class BigRationalExtensions
{
public static string ToDecimalString(this BigRational r, int precision)
{
var fraction = r.GetFractionPart();
// Case where the rational number is a whole number
if(fraction.Numerator == 0 && fraction.Denominator == 1)
{
return r.GetWholePart() + ".0";
}
var adjustedNumerator = (fraction.Numerator
* BigInteger.Pow(10, precision));
var decimalPlaces = adjustedNumerator / fraction.Denominator;
// Case where precision wasn't large enough.
if(decimalPlaces == 0)
{
return "0.0";
}
// Give it the capacity for around what we should need for
// the whole part and total precision
// (this is kinda sloppy, but does the trick)
var sb = new StringBuilder(precision + r.ToString().Length);
bool noMoreTrailingZeros = false;
for (int i = precision; i > 0; i--)
{
if(!noMoreTrailingZeros)
{
if ((decimalPlaces%10) == 0)
{
decimalPlaces = decimalPlaces/10;
continue;
}
noMoreTrailingZeros = true;
}
// Add the right most decimal to the string
sb.Insert(0, decimalPlaces%10);
decimalPlaces = decimalPlaces/10;
}
// Insert the whole part and decimal
sb.Insert(0, ".");
sb.Insert(0, r.GetWholePart());
return sb.ToString();
}
}
10進数または2進数の精度範囲外の場合は、0.0の値でそれぞれのタイプにキャストされます。また、結果が範囲外の場合に10進数にキャストすると、OverflowException
がスローされます。
私が書いた拡張メソッド(分数の小数表現を計算するための最良の方法ではないかもしれません)は、無制限の精度で文字列に正確に変換します。ただし、数値が要求された精度よりも小さい場合は、10進数またはdoubleの場合と同様に、0.0が返されます。