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 中编写了一个高精度浮点类 ( HPF )。而且,是的,以数千位数进行计算是可行的,至少在限制范围内。对于如此庞大的数字,不要期望结果会像闪电一样快。

在这里,在 CPU 时间不到一秒的时间内,使用HPF将 sin(0.5) 计算为 2000 个十进制数字。

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(一个用于指数,一个用于尾数)。有理数是不实用的。

于 2013-08-27T12:12:25.253 回答