除以零的无穷大符号
Sign of infinity on division by zero
我已经实现了在 2D space 中查找点的极坐标的代码。如果该点位于第一或第二象限,0<=theta<=pi
如果它位于第三或第四象限,则 -pi <= theta <= 0
.
module thetalib
contains
real function comp_theta( x1, x2)
implicit none
real , intent(in) :: x1, x2
real :: x1p, x2p
real :: x1_c=0.0, x2_c=0.0
real :: pi=4*atan(1.0)
x1p = x1 - x1_c
x2p = x2 - x2_c
! - Patch
!if ( x1p == 0 .and. x2p /= 0 ) then
! comp_theta = sign(pi/2.0, x2p)
!else
! comp_theta = atan ( x2p / x1p )
!endif
comp_theta = atan( x2p / x1p)
if ( x1p >= 0.0 .and. x2p >= 0.0 ) then
comp_theta = comp_theta
elseif ( x1p < 0 .and. x2p >= 0.0 ) then
comp_theta = pi + comp_theta
elseif( x1p < 0.0 .and. x2p < 0.0 ) then
comp_theta = -1* (pi - comp_theta)
elseif ( x1p >= 0.0 .and. x2p < 0.0 ) then
comp_theta = comp_theta
endif
return
end function comp_theta
end module thetalib
program main
use thetalib
implicit none
! Quadrant 1
print *, "(0.00, 1.00): ", comp_theta(0.00, 1.00)
print *, "(1.00, 0.00): ", comp_theta(1.00, 0.00)
print *, "(1.00, 1.00): ", comp_theta(1.00, 1.00)
! Quadrant 2
print *, "(-1.00, 1.00): ", comp_theta(-1.00, 1.00)
print *, "(-1.00, 0.00): ", comp_theta(-1.00, 0.00)
! Quadrant 3
print *, "(-1.00, -1.00): ", comp_theta(-1.00, -1.00)
! Quadrant 4
print *, "(0.00, -1.00): ", comp_theta(0.00, -1.00)
print *, "(1.00, -1.00): ", comp_theta(1.00, -1.00)
end program main
在函数thetalib::comp_theta
中,当除以零且分子为+ve时,fortran将其计算为-infinity
,当分子为-ve时,将其计算为是 +infinity
(见输出)
(0.00, 1.00): -1.570796
(1.00, 0.00): 0.0000000E+00
(1.00, 1.00): 0.7853982
(-1.00, 1.00): 2.356194
(-1.00, 0.00): 3.141593
(-1.00, -1.00): -2.356194
(0.00, -1.00): 1.570796
(1.00, -1.00): -0.7853982
这让我很困惑。我还实施了您看到的补丁来解决它。为了进一步调查,我设置了一个小测试:
program main
implicit none
real :: x1, x2
x1 = 0.0 - 0.0 ! Reflecting the x1p - 0.0
x2 = 1.0
write(*,*) "x2/x1=", x2/x1
x2 = -1.0
write(*,*) "x2/x1=", x2/x1
end program main
计算结果为:
x2/x1= Infinity
x2/x1= -Infinity
我的 Fortran 版本:
$ ifort --version
ifort (IFORT) 19.0.1.144 20181018
Copyright (C) 1985-2018 Intel Corporation. All rights reserved.
我有三个问题:
- 为什么有符号无限值?
- 符号是如何确定的?
- 为什么
infinity
对 thetalib::comp_theta
和测试程序都采用输出中显示的符号?
您也可以尝试检查数字是否等于它本身。如果不是的话。它是无限的。
EX:if ( x2x1 .eq. x2x1)
然后是好号码。如果不是那么无穷大。
也可能持有 x1 的值是由计算机计算的,其中数字中的所有位都设置为 1(-无穷大)并按位除法得到以下结果:
这实际上是一个减法运算,其中 (0....001 - 01...111) = -Infinity
和 (0....001 - 11.....111) = +Infinity 我会查找按位除法并查看相关信息。更多的已经完成了,但我不需要解释细节。
编译器支持带实数类型的 IEEE 算法,因此存在带符号的无限值。
为了动机,考虑实数非零分子和分母。如果它们都具有相同的符号,则商是实数(有限)正数。如果它们的符号相反,则商是实数(有限)负数。
考虑极限 1/x
,因为 x 从下方趋于零。对于 x
的任何严格负值,该值为负数。出于连续性考虑,可以将极限取为负无穷大。
所以,当分子不为零时,分子和分母同号则商为正无穷,异号则为负。还记得零分母 .
如果您想检查数字,看它是否是有限的,您可以使用内部模块 ieee_arithmetic
的过程 IEEE_IS_FINITE
。此外,该模块具有过程 IEEE_CLASS
,它提供有关其参数的有用信息。除其他事项外:
- 是正数还是负数正常数;
- 是否为正无穷大值或负无穷大值;
- 无论是正零还是负零。
我已经实现了在 2D space 中查找点的极坐标的代码。如果该点位于第一或第二象限,0<=theta<=pi
如果它位于第三或第四象限,则 -pi <= theta <= 0
.
module thetalib
contains
real function comp_theta( x1, x2)
implicit none
real , intent(in) :: x1, x2
real :: x1p, x2p
real :: x1_c=0.0, x2_c=0.0
real :: pi=4*atan(1.0)
x1p = x1 - x1_c
x2p = x2 - x2_c
! - Patch
!if ( x1p == 0 .and. x2p /= 0 ) then
! comp_theta = sign(pi/2.0, x2p)
!else
! comp_theta = atan ( x2p / x1p )
!endif
comp_theta = atan( x2p / x1p)
if ( x1p >= 0.0 .and. x2p >= 0.0 ) then
comp_theta = comp_theta
elseif ( x1p < 0 .and. x2p >= 0.0 ) then
comp_theta = pi + comp_theta
elseif( x1p < 0.0 .and. x2p < 0.0 ) then
comp_theta = -1* (pi - comp_theta)
elseif ( x1p >= 0.0 .and. x2p < 0.0 ) then
comp_theta = comp_theta
endif
return
end function comp_theta
end module thetalib
program main
use thetalib
implicit none
! Quadrant 1
print *, "(0.00, 1.00): ", comp_theta(0.00, 1.00)
print *, "(1.00, 0.00): ", comp_theta(1.00, 0.00)
print *, "(1.00, 1.00): ", comp_theta(1.00, 1.00)
! Quadrant 2
print *, "(-1.00, 1.00): ", comp_theta(-1.00, 1.00)
print *, "(-1.00, 0.00): ", comp_theta(-1.00, 0.00)
! Quadrant 3
print *, "(-1.00, -1.00): ", comp_theta(-1.00, -1.00)
! Quadrant 4
print *, "(0.00, -1.00): ", comp_theta(0.00, -1.00)
print *, "(1.00, -1.00): ", comp_theta(1.00, -1.00)
end program main
在函数thetalib::comp_theta
中,当除以零且分子为+ve时,fortran将其计算为-infinity
,当分子为-ve时,将其计算为是 +infinity
(见输出)
(0.00, 1.00): -1.570796
(1.00, 0.00): 0.0000000E+00
(1.00, 1.00): 0.7853982
(-1.00, 1.00): 2.356194
(-1.00, 0.00): 3.141593
(-1.00, -1.00): -2.356194
(0.00, -1.00): 1.570796
(1.00, -1.00): -0.7853982
这让我很困惑。我还实施了您看到的补丁来解决它。为了进一步调查,我设置了一个小测试:
program main
implicit none
real :: x1, x2
x1 = 0.0 - 0.0 ! Reflecting the x1p - 0.0
x2 = 1.0
write(*,*) "x2/x1=", x2/x1
x2 = -1.0
write(*,*) "x2/x1=", x2/x1
end program main
计算结果为:
x2/x1= Infinity
x2/x1= -Infinity
我的 Fortran 版本:
$ ifort --version
ifort (IFORT) 19.0.1.144 20181018
Copyright (C) 1985-2018 Intel Corporation. All rights reserved.
我有三个问题:
- 为什么有符号无限值?
- 符号是如何确定的?
- 为什么
infinity
对thetalib::comp_theta
和测试程序都采用输出中显示的符号?
您也可以尝试检查数字是否等于它本身。如果不是的话。它是无限的。
EX:if ( x2x1 .eq. x2x1)
然后是好号码。如果不是那么无穷大。
也可能持有 x1 的值是由计算机计算的,其中数字中的所有位都设置为 1(-无穷大)并按位除法得到以下结果:
这实际上是一个减法运算,其中 (0....001 - 01...111) = -Infinity 和 (0....001 - 11.....111) = +Infinity 我会查找按位除法并查看相关信息。更多的已经完成了,但我不需要解释细节。
编译器支持带实数类型的 IEEE 算法,因此存在带符号的无限值。
为了动机,考虑实数非零分子和分母。如果它们都具有相同的符号,则商是实数(有限)正数。如果它们的符号相反,则商是实数(有限)负数。
考虑极限 1/x
,因为 x 从下方趋于零。对于 x
的任何严格负值,该值为负数。出于连续性考虑,可以将极限取为负无穷大。
所以,当分子不为零时,分子和分母同号则商为正无穷,异号则为负。还记得零分母
如果您想检查数字,看它是否是有限的,您可以使用内部模块 ieee_arithmetic
的过程 IEEE_IS_FINITE
。此外,该模块具有过程 IEEE_CLASS
,它提供有关其参数的有用信息。除其他事项外:
- 是正数还是负数正常数;
- 是否为正无穷大值或负无穷大值;
- 无论是正零还是负零。