0

私はSystem.Numerics.BigInteger.Net 4.0とBCLBigRationalのクラスを使用して、数学パーサー/電卓アプリケーションを構築しています。目標は、大きな数をサポートする完全に機能する数学パーサーを作成することです...そのため、数学関数を使用する必要があります。残念ながら、すべての System.Math 関数は float や double などの一般的なデータ型を返すため、あまり正確ではありません。もっと精度が必要です。私はmicrolib.dllを掘り下げましたが、サイン関数については、これを見つけました:

[SecuritySafeCritical, __DynamicallyInvokable]
[MethodImpl(MethodImplOptions.InternalCall)]
public static extern double Sin(double a);

多くの数学関数は .Net に実装されておらず、ハードウェア コードから直接得られることを知っています。これらの関数を使用して、高精度または大きな整数を取得できますか? そうでない場合、それらを自分で実装する最良の方法は何ですか? (パフォーマンスも重要です)リソースや正しい方向性を示していただければ幸いです。

4

2 に答える 2

4

MATLAB で高精度 float クラス ( HPF ) を作成しました。そして、はい、少なくとも制限内で、ここで求められる計算を数千桁で行うことが実用的です。膨大な数の結果が電光石火の速さであるとは思わないでください。

ここでは、1 秒未満の CPU 時間で、 HPFを使用して 2000 桁までの sin(0.5) を計算します。

x = hpf('0.5',2000);
z = sin(x)
z =
0.47942553860420300027328793521557138808180336794060067518861661312553500028781483220963127468434826908613209108450571741781109374860994028278015396204619192460995729393228140053354633818805522859567013569985423363912107172077738015297987137716951517618072114969807370147476869703198703900097339549102989443417733111109673903936124163653480401918346314376284392645260157071283092766006791017533631162287616795734840371866817730333179872034064567347182994506824663612455463453278289361244779536601735462820464717823776898881644512826197840291735466150683689733147287397488788190207928799138423095503817584705030067646428267136203352514539875309014204847017729272889212301417866971280026511717607919387379654420848964303389447566823572876762597714624447000807836928214941991138743810551646471072080462812247422335610868323144633547779337371136437454965479015122728507221582125562761335681781172799521300086891593889552064797344909502979313524137777091507360571026506015248874581726210924892801291055435819896189522803930563792190652684778508854934451273978032859742747386701227727154948654357881637851140514356687525131655792391290065314050467763961605300872097475383191474571466991222453822643126018869834327176291251787779457463370925032134676572752244926564204875494171901976363708322142014379355418299630547673437168013019784069157658698329043158470653971407921567047204742130833307984199944961246141304498844116424471800555566374594078227611966253268668739369977542338090766178818446935337871719545939020589010000184922392803416567433189354514503108047619925727424426280213643488597421990337636199906535549697075412246167977122862009545754093682493517801100883291428841032100118426615836052047298714537824867973933776850058028935197623983399376280971742853670048048344682272994976197375983973258649430222855535025176957323557911906997589014243194056649766589116017811954178461482380269627190632898835306576210057831124120168311609126946042808735584921993653157751619630908157551923919459017792007414

asin(z)
ans =
0.5

asin(z) - x
ans =
3.e-2004

HPF は、Java BigDecimal クラスのような既存のコードに頼ることなく、本質的にゼロから作成し、テストしました。実際、一度は java.math.BigDecimal クラスのオーバーレイとして、クラス全体を数回書きました。私はそれらの実装が気に入らなかったので、最初からやり直して自分で書きました。詳細は、zip に含まれる .pdf ファイルで確認できます。

そうは言っても、一連の実装から何千もの桁を引き出すためのさまざまなトリックを学び、その努力に文字通り人月を費やしました。

そのため、Java の BigDecimal クラスのようなツールを使用したとしても、それらの数値に対して特殊な関数を計算するためのツールを見つけたり構築したりする必要があるでしょう。これは私の時間のほとんどを費やした部分でした。

数千桁で行われるそのような計算は、CPU 時間を有効に使用していますか? あなただけが知っています。個人的には、そのようなツールを書くのはとても楽しかったです。

于 2013-08-27T13:53:34.750 に答える
3

それらを自分で実装する必要があります。三角関数については、テイラー級数を読みたいと思うでしょう。

ただし、これが数千桁の場合に実用的であるとは思えません。そんなに精度が必要ですか?一般に、このような精度が本当に必要な場合は、関数、特に超越関数を評価せず、代わりに記号的に操作する方がよいでしょう。

少なくとも、任意精度の浮動小数点数が必要です。これには BigIntegers を使用できます (1 つは指数用、もう 1 つは仮数用)。有理数は実用的ではありません。

于 2013-08-27T12:12:25.253 に答える