Знак бесконечности при делении на ноль - PullRequest
0 голосов
/ 24 января 2019

Я реализовал код, чтобы найти полярные координаты точки в 2D-пространстве.если точка лежит в 1-м или 2-м квадранте, 0<=theta<=pi, и если она лежит в 3-м или 4-м квадранте, -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, Фортран оценивает его как -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

Моя версия на Фортране:

$ ifort --version
ifort (IFORT) 19.0.1.144 20181018
Copyright (C) 1985-2018 Intel Corporation.  All rights reserved.

И у меня естьтри вопроса:

  1. Почему существуют бесконечные значения со знаком?
  2. Как определяются знаки?
  3. Почему infinity принимает знаки, показанные в выходных данных для обоихthetalib::comp_theta а тестовая программа?

Ответы [ 2 ]

0 голосов
/ 25 января 2019

То, что существуют бесконечные значения со знаком, следует из компилятора, поддерживающего арифметику IEEE с вещественным типом.

Для мотивации рассмотрим действительный ненулевой числитель и знаменатель.Если они оба имеют один и тот же знак, то частное является действительным (конечным) положительным числом.Если они имеют противоположный знак, частное является действительным (конечным) отрицательным числом.

Рассмотрим предел 1/x, когда x стремится к нулю снизу.Для любого строго отрицательного значения x значение является отрицательным.Из соображений преемственности предел можно принять равным отрицательной бесконечности.

Таким образом, когда числитель не равен нулю, частное будет положительной бесконечностью, если числитель и знаменатель имеют один и тот же знак, и отрицательным, еслипротивоположный знак.Напомним также, что нулевой знаменатель может быть подписан .

Если вы хотите проверить число, чтобы увидеть, является ли оно конечным, вы можете использовать процедуру IEEE_IS_FINITE встроенного модуля ieee_arithmetic.Кроме того, этот модуль имеет процедуру IEEE_CLASS, которая предоставляет полезную информацию о своем аргументе.Среди прочего:

  • положительное или отрицательное нормальное число;
  • положительное или отрицательное бесконечное значение;
  • будь то положительный или отрицательный ноль.
0 голосов
/ 25 января 2019

Вы также можете попробовать проверить, равно ли число самому себе.если нет то.это бесконечно.

EX: if ( x2x1 .eq. x2x1) затем ХОРОШИЙ номер.если нет то бесконечность.

Возможно также, что значение, содержащее x1, вычисляется компьютером, где все биты числа установлены в 1 (-infinity), и при делении по битам вы получаете следующее:

который, на самом деле, является операцией вычитания, где (0 .... 001 - 01 ... 111) = -Infinity и (0 .... 001 - 11 ..... 111) = + Infinity Я бы посмотрел побитоворазделите и посмотрите информацию об этом.Больше сделано, но мне не нужно объяснять детали.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...