【问题标题】:How to use math functions with BigInteger and BigRational如何在 BigInteger 和 BigRational 中使用数学函数
【发布时间】:2013-08-29 20:07:54
【问题描述】:

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

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

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

【问题讨论】:

  • 据我所知,十进制类型比精度高一倍
  • 是的,但这也不够精确!我需要更高的精度,比如大约一千个十进制数字。
  • 这取决于你需要多少位数,因为速度加倍将是一个更好的解决方案。编辑:因为你写了你需要更精确:你知道 j++ 运行时的 BigDecimal 类型吗?跨度>
  • 谢谢,但是微软仍然支持 j++ 吗?如果是,我如何在 C# 中使用它?

标签: c# math


【解决方案1】:

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

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

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

【讨论】:

    【解决方案2】:

    您需要自己实现它们。对于三角函数,您需要阅读Taylor series

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

    至少,您需要一个任意精度的浮点数。您可以为此使用 BigIntegers(一个用于指数,一个用于尾数)。有理数是不实用的。

    【讨论】:

    • 感谢您为我指明正确的方向。我现在就开始写我的课!
    猜你喜欢
    • 1970-01-01
    • 2022-01-11
    • 1970-01-01
    • 1970-01-01
    • 2012-02-22
    • 2021-08-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多