除以零的无穷大符号

时间:2019-01-24 18:19:41

标签: fortran intel-fortran

我已实现代码来查找2D空间中点的极坐标。如果该点位于第一象限或第二象限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时,它将求值为{ {1}}(请参见输出)

+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

我的fortran版本:

 x2/x1=       Infinity
 x2/x1=      -Infinity

我有三个问题:

  1. 为什么有符号的无穷大值?
  2. 如何确定标志?
  3. 为什么$ ifort --version ifort (IFORT) 19.0.1.144 20181018 Copyright (C) 1985-2018 Intel Corporation. All rights reserved. 会使用infinity和测试程序的输出中显示的符号?

2 个答案:

答案 0 :(得分:1)

您也可以尝试检查数字是否等于自己。如果没有的话。它是无限的。

EX:if ( x2x1 .eq. x2x1),然后是好号码。如果不是,那么无限。

可能还有x1的值是由计算机计算出来的,其中数字中的所有位都设置为1(无穷大),并且按位除法会得到以下结果:

实际上是一个减法运算,其中(0 .... 001-01 ... 111)=-无穷大  和(0 .... 001-11 ..... 111)= + Infinity我将按位查找并查看该信息。还可以做更多的事情,但是我不需要解释细节。

答案 1 :(得分:1)

编译器支持带实数类型的IEEE算术运算符后,带符号的无穷大值。

出于动机,考虑实数非零分子和分母。如果它们都是相同的符号,则商为实(有限)正数。如果它们的符号相反,则商为实(有限)负数。

考虑极限1/x,因为x从下面趋于零。对于x的任何严格负值,该值为负。出于连续性考虑,该限制可以视为负无穷大。

因此,当分子非零时,如果分子和分母具有相同的符号,则商将为正无穷大;如果具有相反的符号,则商将为负。还记得零分母may be signed

如果要检查该数字,以查看其是否有限,可以使用内部模块IEEE_IS_FINITE的过程ieee_arithmetic。此外,该模块具有过程IEEE_CLASS,该过程提供有关其参数的有用信息。除其他外:

  • 它是正数还是负数正常
  • 它是正无穷大还是负无穷大;
  • 它是正零还是负零。