非常大数字的正弦的标准

时间:2011-07-12 14:02:33

标签: floating-point decimal ieee-754

我正在TeX中编写一个(几乎)IEEE 854兼容的浮点实现(它只支持32位整数)。此标准仅指定+-*/,比较,余数和sqrt的结果:对于这些操作,结果应该是与将确切结果四舍五入到可表示的数字相同(根据舍入模式)。

我似乎记得IEEE规定超越函数(sinexp ...)应该产生忠实的结果(在默认的舍入到最接近的模式中,它们应该输出一个围绕确切结果的两个可表示的数字)。计算小数的正弦是相当简单的:移动2 * pi的倍数以获得[0,2 * pi]范围内的数字,然后再做一些工作以将范围缩小到[0,pi / 4] ,并使用泰勒系列。

现在假设我想计算罪(1e300)。为此,我需要找到1e300 modulo 2 * pi。这需要知道pi的300(316?)小数,因为只有16位小数,结果没有任何意义(特别是,它不忠实)。

sin(1e300)和类似的非常大的数字的结果是否有标准?

其他浮点实现有什么作用?

2 个答案:

答案 0 :(得分:9)

没有标准要求忠实地舍入超越功能。 IEEE-754(2008)建议,但不要求这些功能正确舍入。

大多数优秀的数学图书馆都努力在整个范围内提供忠实圆润的结果(是的,即使对于sin( )和类似的困难案例的巨大输入也是如此)。正如您所注意到的,这要求库知道更多的π数字,然后在最大可表示数字中有数字。这被称为“无限pi”参数减少。

对于@spraff提出的点,好的数学库采用输入无限精确的观点(即,该函数应该表现得好像输入总是准确地表示)。人们可以辩论这是否是一个合理的位置,但这是基本上所有优秀数学库的工作假设。

所有这一切都说,有很多库采用简单的路径并使用“有限pi”减少,它基本上处理像sin( )这样的函数,好像π是可表示的有限数。事实证明,这对大多数使用并没有造成任何麻烦,而且肯定更容易实现。

答案 1 :(得分:1)

如果你在如此庞大的数字上进行操作,当然你会用完精确度:

#include <iostream>
#include <math.h>

int main () {
    long double i = 1;
    std :: cout << sin (i) << "\n" << sin (i+0.1) << "\n";
    i = pow (10, 300);
    std :: cout << sin (i) << "\n" << sin (i+0.1);
}

输出:

  

0.841471

     

0.891207

     

-0.817882

     

-0.81788

如果无法准确表示输入,则无法准确表示输出。减去pi*pow(10,int(log_10(n/pi))或任何会使“小”n更糟糕的事情,但当n变得相当大时,你只是在噪音中添加噪音而且不再重要