【问题标题】:How to compute correctly rounded trigonometric functions in degrees?如何以度为单位计算正确舍入的三角函数?
【发布时间】:2014-09-26 02:43:38
【问题描述】:

我如何定义以度数而不是通常的弧度为参数的三角函数,并为这些参数计算正确的四舍五入结果?

在将参数传递给以弧度表示的相应函数之前,将参数乘以 M_PI/180.0 是行不通的,因为 M_PI/180.0 不是 π/180。 Handbook of Floating-Point Arithmetic 的第 5.5 节提供了一种计算参数正确舍入乘积 π/180 的方法,但有些参数仍然会使得该乘积接近两个连续可表示浮点数之间的中点,然后即使在弧度中应用正确舍入的函数也会产生错误的最终结果。

可以单独使用或组合使用的两种策略是使用更高的精度和使用来自CRlibmsinpicospitanpi 三角函数,它们分别计算sin(πx)cos(πx) 和@987654329 @。

对于后一种策略,仍然存在除以 180 的问题,这对于许多论点来说并不准确。

关于更高精度的策略(将参数乘以 π/180 的扩展精度表示,然后以弧度应用扩展精度函数),“精确”情况可能仍然存在问题。指出sincostan 的唯一理性结果的定理在0 中获得仅适用于弧度版本。它显然不适用于度数版本,如果对于某些浮点输入 x,sindeg(x) 恰好是两个连续可表示浮点数之间的中点,那么再多的中间精度都不足以保证最终结果被正确四舍五入。

【问题讨论】:

    标签: floating-point trigonometry degrees elementary-functions


    【解决方案1】:

    cosdeg(360q) 是有理数的唯一有理数 q 有 1、2、3、4 或 6 作为分母。 This paper 由 Joerg Jahnel 在第 6 节中包含一个使用场论的简短而漂亮的证明。(实际上,作者使用欧拉的总函数来表征代数数 cosdeg(360q) 的度数。)所以没有浮点 q这样cosdeg(360q) 在两个相邻浮点数之间。

    所以我猜答案是“与您实现sin 和弧度朋友的方式大致相同”,尽管@gnasher729 提出了一个很好的观点,即度数的参数减少要好得多。

    【讨论】:

    • 我会立即继续阅读这篇论文,但推断浮点sindeg 没有重要的确切情况的结果不应该是“没有浮点-指向q 使得sindeg(q) 在两个相邻浮点数之间”?
    • @PascalCuoq:是的。我(错误)引用的结果说,导致sindeg(q)cosdeg(q) 的合理(不要介意两个相邻浮点之间的中间值)值的唯一合理q 是30 度的倍数,其中答案总是无理数或 1/2 的倍数。这是一个比您需要的结果更强大的结果,因为每个浮点和每个浮点之间的中间值都是合理的。
    • 其实我更欣赏第 3 节中的基本证明(虽然它只涵盖了 sindeg 和 cosdeg)。
    • @PascalCuoq:如果你想得到类似的棕褐色结果,oberlin.edu/faculty/jcalcut/tanpap.pdf 看起来不错。
    【解决方案2】:

    这很难。从积极的方面来说,您可以将参数精确地减小到 +/- 45 度。因此,您需要在 +/- 45 度之间正确舍入结果。对于非常小的 x,sin (x) 大约是 x * (pi / 180),这很难精确地四舍五入。

    例如,要获得正弦函数的最正确舍入结果,请取 -45

    【讨论】:

      【解决方案3】:

      嗯,这是一个难题。让我澄清一些观点:

      • 输出需要什么精度?它是 IEEE 754 单精度或双精度还是非标准?此外,我假设输入,即以度数表示的输入,应该以与输出相同的精度表示,因为这是正常弧度输入的情况。
      • 您的绩效指标是什么? CRlibm 经过优化以产生正确舍入的双精度结果。另一方面,MPFR 用于任意精度,但当您只需要双精度输出时,它比 CRlibm 慢得多。
      • 您的工作范围是多少?即[最小参数,最大参数]?这对 CRlibm 很重要,因为它适用于双精度范围。不过,这对 MPFR 来说并不重要。

      如果您必须仅使用度数输入,我基本上建议使用 MPFR。让我提醒你,任何以度为单位的参数,当它乘以 (Pi/180) 时,它会产生一个超越数。然而,传递给三角函数的是浮点表示,四舍五入,最好是四舍五入到最接近的整数,以达到工作精度。

      我建议你这样做:

      1. 使用 MPFR,尽可能使用 C 库,因为它提供比绑定更好的性能。
      2. 将 MPFR 精度设置为远高于目标精度。例如(目标精度 + 300)。通过这样做,您可以避免操作 ((Argument*Pi)/180) 的任何准确性损失。 这可以通过 mpfr_set_default_prec() 在 MPFR C 库中轻松完成。
      3. 执行以下操作:X_n=(Argument*Pi)/180,然后执行 Sin(X_n) 或任何您想要的函数。 MPFR 中有一个常数 Pi,它在您的工作精度内表示
      4. 将结果四舍五入到目标精度。

      Muller 的“基本函数”从统计上表明,如果工作精度略大于目标精度的两倍,则大多数(并非所有)困难情况都会正确舍入。但是在您的情况下,由于输入在理论上是超越的,为了安全起见,以牺牲性能为代价,使工作精度远高于目标。实际上,如果您需要高达双精度的最终结果,对于几乎 100% 的情况,10 倍是完全足够的。

      如果您需要较低的精度,即单精度或更低,可以进行详尽的测试以确定最低工作精度,从而使所有情况都正确舍入。

      【讨论】:

      • 1- 如果存在可表示的浮点参数,其图像恰好是两个可表示的连续浮点值之间的中点,则“将 MPFR 精度设置为远高于目标精度”不起作用。如果我没有在我的问题中说清楚,我很抱歉,但这就是“确切的”案例可能仍然存在问题”的意思。已经指出,人们不必担心 sin、cos 和 tan 的确切情况。
      • 2-“通过这样做,您可以避免操作 ((Argument*Pi)/180) 的任何准确性损失” MPFR 是二进制的,将会损失准确性。例如,tandeg(90) 为您的提案提供了一个大但有限的值,四舍五入到目标精度的某个无穷大。正确的结果是 NaN。
      • 超越函数的输出,例如 sin、cos、log,不能正​​好是中点。实际输出必须是超越数。
      • 是的,这是我的问题的一部分,tmyklebu 已经回答了。然而,在他回答之前,sindeg、cosdeg 和 tandeg 没有任何确切的案例并不明显。请注意,我对 sindeg、cosdeg 和 tandeg 感兴趣。关于 sin、cos、tan 的定理并不直接适用。
      • 是的,它会给出一个很大的有限数,因为输出没有超过最大值。我提醒您,如果您使用 MPFR,默认情况下它会设置非常高的最大值。因此我假设你没有超过最大值。
      【解决方案4】:

      您首先需要检测确切的案例,这已经得到解答。现在,对于其他情况,有一个众所周知的制表者困境问题。如果您的算术具有固定(且较小)的精度,并且您希望在可能需要的中间精度上获得经过认证的界限,则有两种已知的解决方案:

      • 根据我的博士论文第 4.3 节所述,根据 Nesterenko 和 Waldschmidt 定理获得一个界限(顺便说一句,我认为这也会为您提供确切案例的形式)。但是你会得到非常大的精度界限(至少几百万位?)。
      • 找到最难圆的箱子。在 [0,180] 中进行搜索就足够了,因为任何较大的参数都将减少到 [0,180] 中的值,并且具有相同的小数部分(因为句点是整数)。

      【讨论】:

        猜你喜欢
        • 2017-01-13
        • 2020-04-01
        • 1970-01-01
        • 1970-01-01
        • 2015-04-20
        • 2011-11-18
        • 2012-04-15
        • 2016-01-05
        • 2016-09-21
        相关资源
        最近更新 更多