除以零的无穷大符号 [英] Sign of infinity on division by zero
问题描述
我已经实现了在2D空间中查找点的极坐标的代码.如果该点位于第一象限或第二象限中,则 0< = theta< = pi
,如果它位于第三象限或第四象限中,则 -pi< = theta< = 0
.
I've implemented code to find the polar coordinates of a point in 2D space. if the point lies in the 1st or 2nd Quadrant, 0<=theta<=pi
and if it lies in the 3rd or 4th Quadrant, -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
(请参见输出)
In the function thetalib::comp_theta
, when there is a division by zero and the numerator is +ve, fortran evaluates it to be -infinity
and when the numerator is -ve, it evaluates it to be +infinity
( see output )
(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
这让我感到困惑.我还实现了您认为可以解决该问题的补丁.为了进一步调查,我设置了一个小测试:
This baffled me. I've also implemented the patch you see to work around it. And to investigate it further, I setup a small test:
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版本:
My fortran version:
$ ifort --version
ifort (IFORT) 19.0.1.144 20181018
Copyright (C) 1985-2018 Intel Corporation. All rights reserved.
我有三个问题:
- 为什么有符号的无穷大值?
- 如何确定标志?
- 为什么
infinity
对thetalib :: comp_theta
和测试程序都采用输出中显示的符号?
- Why there are signed infinite values?
- How are the signs determined?
- Why does
infinity
take the signs shown in outputs for boththetalib::comp_theta
and the test program?
推荐答案
编译器支持带实数类型的IEEE算术运算符,后面有带符号的无穷大值.
That there are signed infinite values follows from the compiler supporting IEEE arithmetic with the real type.
出于动机,考虑实数非零分子和分母.如果它们都是相同的符号,则商为实(有限)正数.如果它们的符号相反,则商为实(有限)负数.
For motivation, consider real non-zero numerator and denominator. If these are both of the same sign then the quotient is a real (finite) positive number. If they are of opposite sign the quotient is a real (finite) negative number.
考虑极限值 1/x
,因为x从下往上趋于零.对于 x
的任何严格负值,该值为负.出于连续性考虑,该限制可以视为负无穷大.
Consider the limit 1/x
as x tends to zero from below. For any strictly negative value of x
the value is negative. For continuity considerations the limit can be taken to be negative infinity.
因此,当分子非零时,如果分子和分母具有相同的符号,则商将为正无穷大;如果具有相反的符号,则商将为负.还记得零分母可以被签名.
So, when the numerator is non-zero, the quotient will be positive infinity if the numerator and denominator are of the same sign, and negative if of opposite sign. Recall also, that the zero denominator may be signed.
如果要检查该数字,以查看其是否有限,可以使用内部模块 ieee_arithmetic
的过程 IEEE_IS_FINITE
.此外,该模块具有过程 IEEE_CLASS
,该过程提供有关其参数的有用信息.除其他外:
If you wish to examine the number, to see whether it is finite you can use the procedure IEEE_IS_FINITE
of the intrinsic module ieee_arithmetic
. Further, that module has the procedure IEEE_CLASS
which provides useful information about its argument. Among other things:
- 它是正数还是负数正常;
- 它是正无穷大还是负无穷大;
- 它是正零还是负零.
这篇关于除以零的无穷大符号的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!