Floating point 超大数正弦的标准

Floating point 超大数正弦的标准,floating-point,decimal,ieee-754,Floating Point,Decimal,Ieee 754,我正在编写一个(几乎)符合IEEE 854的TeX浮点实现(它只支持32位整数)。本标准仅规定了+、-、*、/、比较、余数和sqrt:对于这些操作,结果应与将精确结果四舍五入到可表示数字的结果相同(根据舍入模式) 我似乎记得IEEE规定超越函数(sin,exp…)应该产生忠实的结果(在默认的四舍五入模式中,它们应该输出围绕精确结果的两个可表示数字中的一个)。计算小数值的正弦非常简单:移动2*pi的倍数以获得[0,2*pi]范围内的数字,然后再做一些工作将范围缩小到[0,pi/4],并使用泰勒级数

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

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

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

对于sin(1e300)和类似的非常大的数字的结果应该是什么,是否有一个标准


其他浮点实现会做什么?

如果要对如此大的数字执行操作,那么当然会耗尽精度:

#包括
#包括
int main(){
长双i=1;

std::cout没有标准要求对超越函数进行可靠的四舍五入。IEEE-754(2008)建议但不要求这些函数正确四舍五入

大多数优秀的数学库都努力在整个范围内提供忠实的四舍五入结果(是的,即使是对
sin()
的大量输入和类似的困难情况也是如此)。正如您所注意到的,这要求库知道更多π的位数,然后在最大的可表示数中有位数。这称为“无限π”论点简化

就@spraff提出的观点而言,好的数学库采用的观点是,输入是无限精确的(即,函数的行为应该像输入总是被精确地表示一样)。人们可以争论这是否是一个合理的位置,但这基本上是所有好的数学库的工作假设


综上所述,有很多库采用简单的方法,使用“有限pi”缩减,基本上处理函数
sin()
就好像π是一个可表示的有限数。事实证明,对于大多数应用来说,这并不会带来任何麻烦,而且更容易实现。

+1对一个有趣问题的很好的解释(我以前没有想过)或者更简单地说,
1e300+2pi
=
1e300-2pi
=
1e300
,因此
1e300
表示的可能精确值可以有任何值作为其
sin
?@Damien\u不相信者,当
1e300
四舍五入到最接近的
double
表示值时,四舍五入超过一个区间长度l大约为
1e284
。因此,当我们将
1e300
四舍五入到一个可表示的
double
时,我们“通过”非常多的
2pi
长度周期。因此取
sin
是毫无意义的。但是,从数学上讲,在我们将参数四舍五入到一个可表示的值后,可以计算该确切参数的
sin
。要做到这一点,需要对
2pi
的表示进行大量的精确计算。正如我在中所说的对另一个答案的注释,在.NET中,
Sin(1e300)=1e300
“无限pi参数缩减”当你有大参数时会有帮助,但当你有非常大的参数时则不会。库可以假定它的输入是准确的,但当输入+ε==input时,它就不再重要了。@spraff:对于向后错误分析来说,这不重要了。当使用其他形式的错误分析时,它才重要,这就是问题所在最好的数学库所遵循的标准。例如,请参阅K.C.Ng的“好到最后一点”进行讨论。在您的第三段中,您可以注意到好的库可以做到这一点,因为IEEE-754(2008)认为浮点数是无限精确的。您能举一个“好的数学库”与这些库的例子吗“走简单的路线”?我想这会增加你的答案。简单路线不会造成太多麻烦的一个原因是它不会违反三角恒等式,比如sin(2x)=2*sin(x)*cos(x)@Bruno:如果你只需要两个实现来匹配,你可以对两个实现使用相同的有限pi近似值。只要你小心地用同样的方法对这两个实现进行运算,这就足够了。@BrunoLeFloch.NET的库几乎不“好”。我刚刚意识到当参数超过
Pow(2,63)时
,该方法返回其参数不变!因此当
Sin(9.223372036854775E+18)==0.98734189131435146
可能不精确时,
Sin(9.223372036854776E+18)
大约是
9.22E+18
。。。