非常大数的正弦标准
我正在 TeX 中编写一个(几乎)符合 IEEE 854 的浮点实现(仅支持 32 位整数)。本标准仅规定了+
、-
、*
、/
、比较、余数、的结果>sqrt
:对于这些操作,结果应该与将精确结果四舍五入到可表示的数字相同(根据舍入模式)。
我似乎记得 IEEE 指定超越函数(sin
、exp
...)应该产生忠实的结果(在默认的舍入到最近模式下,它们应该输出围绕确切结果的两个可表示数字之一)。计算小数的正弦相当简单:移位 2*pi 的倍数以获得 [0,2*pi] 范围内的数字,然后做更多工作将范围缩小到 [0,pi/4] ,并使用泰勒级数。
现在假设我要计算 sin(1e300)。为此,我需要找到 1e300 模 2*pi。这需要知道 pi 的 300(316?) 位小数,因为只有 16 位小数,结果就没有任何意义(特别是,它不忠实)。
对于 sin(1e300)
和类似的非常大的数字的结果应该是什么有一个标准吗?
其他浮点实现有什么作用?
I am writing an (almost) IEEE 854 compliant floating point implementation in TeX (which only has support for 32-bit integers). This standard only specifies the result of +
, -
, *
, /
, comparison, remainder, and sqrt
: for those operations, the result should be identical to rounding the exact result to a representable number (according to the rounding mode).
I seem to recall that IEEE specifies that transcendental functions (sin
, exp
...) should yield faithful results (in the default round-to-nearest mode, they should output one of the two representable numbers surrounding the exact result). Computing the sine of small numbers is rather straightforward: shift by a multiple of 2*pi to obtain a number in the range [0,2*pi], then do some more work to reduce the range to [0,pi/4], and use a Taylor series.
Now assume that I want to compute sin(1e300). For that I would need to find 1e300 modulo 2*pi. That requires to know 300 (316?) decimals of pi, because with only 16 decimals, the result would have no significance whatsoever (in particular, it souldn't be faithful).
Is there a standard on what the result of sin(1e300)
and similar very large numbers should be?
What do other floating point implementations do?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
没有标准要求对超越函数进行忠实舍入。 IEEE-754 (2008) 建议但不要求这些函数正确舍入。
大多数优秀的数学库都致力于在整个范围内提供忠实的舍入结果(是的,即使对于
sin( )
的大量输入和类似的困难情况也是如此)。正如您所注意到的,这要求库知道的 π 位数比最大可表示数中的位数要多一些。这称为“无限 pi”参数缩减。对于@spraff 提出的观点,好的数学库采用输入无限精确的观点(即,函数的行为应该就像输入始终准确表示一样)。人们可以争论这是否是一个合理的立场,但这基本上是所有优秀数学库的工作假设。
话虽如此,有很多库采取了简单的方法并使用“有限 pi”约简,这基本上将像
sin( )
这样的函数视为 π 是一个可表示的有限数。事实证明,这对于大多数用途来说并没有真正造成任何麻烦,而且当然更容易实现。There is no standard that requires faithful rounding of transcendental functions. IEEE-754 (2008) recommends, but does not require, that these functions be correctly rounded.
Most good math libraries strive to deliver faithfully rounded results over the entire range (yes, even for huge inputs to
sin( )
and similarly hard cases). As you note, this requires that the library know somewhat more digits of π then there are digits in the largest representable number. This is called an "infinite-pi" argument reduction.To the point that @spraff raises, good math libraries adopt the viewpoint that the inputs are infinitely precise (i.e., the function should behave as though the input is always represented accurately). One can debate whether or not this is a reasonable position, but thats the working assumption for essentially all good math libraries.
All that said, there are plenty of libraries that take the easy route and use a "finite-pi" reduction, which basically treats a function like
sin( )
as though π were a representable finite number. It turns out that this doesn't really cause any trouble for most uses, and is certainly easier to implement.如果你对如此大的数字进行运算,当然你会失去精度:
输出:
如果无法准确表示输入,则无法准确表示输出。减去
pi*pow(10,int(log_10(n/pi))
或其他任何方法都会使“小”n
的情况变得更糟,但是当n< /code> 变得适当大,你只是将噪音添加到噪音中,这不再重要了。
If you're doing operations on such large numbers, of course you're going to run out of precision:
Output:
If you can't represent the inputs accurately, you can't represent the outputs accurately. Subtracting
pi*pow(10,int(log_10(n/pi))
or whatever is going to make things worse for "small"n
but whenn
gets suitably large, you're just adding noise to noise and it doesn't matter any more.