如何使用BigInteger和BigRational的数学函数

时间:2013-08-27 07:18:44

标签: c# math

我在.Net 4.0中使用System.Numerics.BigInteger,在BCL使用BigRational类来构建数学解析器/计算器应用程序。目标是编写一个功能齐全的数学解析器,支持大数...所以我需要使用数学函数。但不幸的是,所有System.Math函数都返回典型的数据类型,如float和double,因此不是很准确。我需要更高的精度。我挖到了microlib.dll,但是对于正弦函数,我发现了这个:

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

我知道很多数学函数都没有在.Net中实现,而是直接来自硬件代码。那么我可以使用这些功能并获得高精度或大整数吗?如果没有,自己实施它们的最佳方法是什么? (表现也很重要)任何资源或指向正确的方向都会受到赞赏!

2 个答案:

答案 0 :(得分:3)

您需要自己实施。对于trig函数,您需要阅读Taylor series

但是,我怀疑这对于数千位数字来说是实用的。你真的需要那么精确吗?一般来说,如果确实需要像这样的精度,那么最好不要评估函数,特别是超越函数,而是象征性地使用它们。

至少,你需要一个任意精度的浮点数。您可以使用BigIntegers(一个用于指数,一个用于尾数)。理性数字是不切实际的。

答案 1 :(得分:3)

我在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时间?只有你知道。就个人而言,编写这样的工具非常有趣。

相关问题