12

C#でBigIntegerクラスを正確に除算する必要があるクラスを作成しています。

例:

BigInteger x = BigInteger.Parse("1000000000000000000000000000000000000000000000000000000000000000000000000000000000000");
BigInteger y = BigInteger.Parse("2000000000000000000000000000000000000000000000000000000000000000000000000000000000000");

x /= y;

Console.WriteLine(x.ToString());

//Output = 0

問題は、整数であるため、当然、10進値を保持しないことです。これをどのように克服して、0.5の実際の結果を得ることができますか(与えられた例)。

PSソリューションは、例だけでなく、BigIntegerを正確に分割できる必要があります。

4

7 に答える 7

17

上記の例では、数値は に変換できるほど小さいdoubleので、この場合は次のように言えます。

double result = (double)x / (double)y;

xyが大きすぎて比較できない場合はdouble、次のすばらしいトリックが役立つかもしれません。

double result = Math.Exp(BigInteger.Log(x) - BigInteger.Log(y));

しかし、一般に、BigIntegerが巨大で、その商も巨大な場合、サードパーティのライブラリをインポートしないとこれを行うのは困難です。

于 2012-08-08T07:03:20.150 に答える
7

割り算に必要な精度は?1つの方法は次のとおりです。

  • 分子に、たとえば 1000 を掛けます。
  • 数字を割ります
  • 結果を に変換し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);
于 2012-08-08T06:56:41.717 に答える
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実装が必要です。

Microsoft Solver Foundation 3.0にも実装されたRational 構造があります。執筆時点では、www.solverfoundation.com サイトが壊れていたため、アーカイブへのリンクがありました。

于 2012-08-08T07:05:26.703 に答える
0

ご存じかもしれませんが、整数の除算では 10 進値が生成されないため、結果は 0 に切り捨てられます。この質問によると、 big double の実装はこちらにありますが、最後のリリースは 2009 年でした。さらに調べてみると、より新しいものを見つけることができます。または、これは単に終了しました。

于 2012-08-08T06:57:41.957 に答える
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;
于 2018-01-19T15:02:35.347 に答える
0

(浮動小数点ではなく)固定小数点の仕事のように聞こえます。

次のように、必要な小数ビットの数だけ分子を事前にシフトするだけです。

BigInteger quotient = (x << 10) / y;

これにより、ドットの後に 10 ビット (10 進数で約 3 桁) が得られます。

于 2012-08-08T07:17:19.297 に答える
-1

2 倍に解析します。

double a = Convert.ToDouble(x);
double b = Convert.ToDouble(y);

Console.WriteLine(a / b);
于 2012-08-08T06:54:41.910 に答える