为什么在C语言中,cexp(+无穷大+I *无穷大)= +/-无穷大+I * NaN?

6
如果我们查看C语言的委员会草案:n1570,特别是关于复杂数学函数行为的Annex G,我们可以看到复指数在无限远处的行为如下:
cexp(+infinity+I*infinity)=+/-infinity+I*NaN
(where the sign of the real part of the result is unspecified).

我的问题是:为什么?

从数学角度来看,如果我们以同样的方式接近实部和虚部的无穷大,极限就是一个复数无穷大(例如,请参见Wolfram Alpha),它对应于无限模和未定义的参数。

此外,如果我们观察cexp函数的行为,它的实部和虚部非常相似(请参见Wolfram Alpha上的三维图形)。

因此,我本来期望:

cexp(+infinity+I*infinity)=+/-infinity+/-I*infinity

替代方案:

cexp(+infinity+I*infinity)=+/-infinity+I*NaN

我知道这背后有很好的理由,但我不明白它的逻辑。有人可以解释一下吗?
编辑:这里是链接的摘要:Summary

2
文档《国际标准理由--编程语言--C》的G.5.1部分似乎包含了一些关于处理复杂函数特殊值(包括cexp())的相关评论。您可以在此处找到它:http://www.open-std.org/jtc1/sc22/wg14/www/C99RationaleV5.10.pdf - njuffa
谢谢提供这个链接。它非常有教育意义,但是它并没有回答关于cexp(infinity+I*infinity)的情况。 - Vincent
我所知道的唯一解释标准委员会思考过程的文件是理由文件。除非您能够找到相关的委员会会议记录(我不知道ISO委员会是否提供公开记录),或者可以接触到委员会成员,否则对于为什么标准规定了什么,这个问题将无法得到回答。 - njuffa
2个回答

2
动机确实在由njuffa链接的文档中给出,链接如下:http://www.open-std.org/jtc1/sc22/wg14/www/C99RationaleV5.10.pdf:
7.3.9.4 函数cproj
复数数学中常用两种拓扑:具有无限多点的复平面和具有单一点无穷远处的黎曼球面。复平面更适合于超越函数,而黎曼球面则更适合于代数函数。复数类型的无限多点提供了一个有用的(尽管不完美)模型,可以帮助建立复平面。 cproj函数通过将所有无限点映射到一个点来模拟黎曼球面,并且应该在任何操作之前(特别是比较)使用,以避免产生其他无限点的虚假结果。
请注意,一个具有一个无穷大部分和一个NaN部分的复数值被认为是无限大,而不是NaN,因为如果一个部分是无穷大,则复数值是无限大的,而与另一部分的值无关。出于相同的原因,如果cabs的参数具有一个无穷大部分和一个NaN部分,则返回无穷大。
G.5.1中也有类似的注释:
...为了支持单无穷大模型,C99将具有至少一个无限部分的任何复数值都视为复数无穷大(即使另一部分是NaN),并保证操作和函数遵守无穷大的基本属性,并提供cproj函数来将所有无穷点映射到一个标准点。
相关搜索术语为“Riemann”,即带有单一无穷处的扩展复平面的数学模型,该模型在Mathematica / Wolfram Alpha中使用,但不是普遍适用于数学。

0

NaN的一个原因是没有表示这个无限值“方向”的方法。对于实数,lim a->inf : exp(a) -> + infinity。而有明确定义的方向可以直观地解释为为什么:

1/(+0) = +inf1.0 / (-0.0) = -inf以及:

1/(+inf) = +01/(-inf) = -0

将其扩展到复数平面:cexp([-]inf + b.I) = [-]inf.{cos(b) + I.sin(b)}

即使结果具有无限的大小,仍然有一个方向的概念,例如,如果b = - PI/2 -> cexp(+inf + b.I) = +inf.(-I)

如果 b = [-]inf,那么无穷逼近的方向是不确定的。有无数个方向,并且 cos(b)sin(b) 的值未定义。毫不奇怪,实值函数 cos[f|l]sin[f|l] 如果参数是无穷大,则返回 NaN
这并不是一个非常正式的答案,恐怕只是对这个想法的"感觉"。我的理解是,还有其他很好的原因来解释这种行为,比如在复分析中使用分支割线。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接