fortran浮点运算

时间:2016-10-19 10:20:03

标签: floating-point fortran

我有一个Fortran例程来计算浮点运算系统的参数。但是,在我的机器上,这最终会无限循环。但是如果我在循环中添加一个额外的print语句,它将逃脱循环。 print语句是否以某种方式迫使Fortran进行评估?我正在使用:

简而言之

ifort (IFORT) 16.0.3 20160415

oner  = 1._O
zeror = oner - oner
do
          it = it + 1
          b  = b * beta
          temp  = b + oner
          temp1 = temp - b
          if (itemp /= zeror) exit

结束

有了这个额外的print语句,它不会以无限循环结束:

oner

oner  = 1._O
zeror = oner - oner
do
          it = it + 1
          b  = b * beta
          temp  = b + oner
          temp1 = temp - b
          print *, temp1 - oner           <------
          if (itemp /= zeror) exit
end do

我用

编译代码
ifort -parallel -openmp -O3 -xT -axT 

完成例行评论

subroutine machr ( ibeta, it, irnd, ngrd, machep, negep, iexp, minexp, maxexp,      &
           eps, epsneg, xmin, xmax)
!-----------------------------------------------------------------------------------
! The routine computes the parameters of the floating-point arithmetic system.     !
!                                                                                  !
! Output parameters:                                                               !
! - ibeta (integer) - the radix for the floating-point representation.             !
! - it (integer) - the number of base ibeta digits in the floating-point           !
!   significand.                                                                   !
! - irnd (integer) - specifies if floating-point addition chops or rounds          !
!   appear.                                                                        !
! - ngrd (integer) - the number of guard digits for multiplication with            !
!   truncating arithmetic.                                                         !
! - machep (integer) - the largest negative integer such that                      !
!   1.0 + real(ibeta) ** machep /= 1.0.                                            !
! - negeps (integer) - the largest negative integer such that                      !
!   1.0 - real(ibeta) ** negeps /= 1.0.                                            !
! - iexp (integer) - the number of bits reserved for the representation of         !
!   the exponent of a floating-point number.                                       !
! - minexp (integer) - the largest in magnitude negative integer such that         !
!   real(ibeta) ** minexp is positive and normalized.                              !
! - maxexp (integer) - the smallest positive power of beta that overflows.         !
! - eps (real) - the smallest positive floating-point number such that             !
!   1.0 + eps /= 0.0.                                                              !
! - epsneg (real) - the smallest positive floating-point number such that          !
!   1.0 - epsneg /= 0.0.                                                           !
! - xmin (real) - the smallest non-vanishing normalized floating-point power.      !
!   of the radix: xmin = real(ibeta) ** minexp.                                    !
! - xmax (real) - the largest finite floating-point number.                        !
!   xmax = (1.0 - epsneg) * real(ibeta) ** maxexp.                                 !
!-----------------------------------------------------------------------------------
  use parameters
  implicit none
  integer  :: ibeta, it, irnd, ngrd, machep, negep, iexp, minexp, maxexp
  real(O)  :: eps, epsneg, xmin, xmax
!
  integer  :: i, itemp, iz, j, k, mx, nxres
  real(O)  :: a, b, beta, betah, betain, oner, t, temp, temp1, tempa, twor,          &
              y, z, zeror
!
  oner  = 1._O
  twor  = oner + oner
  zeror = oner - oner
  a = oner
  do
    a = a + a
    temp  = a + oner
    temp1 = temp - a
    print *, 'a', temp1 - a
    if (temp1 - oner /= zeror ) exit
  end do
  b = oner
  do


    b = b + b
    temp  = a + b
    itemp = int (temp - a)
    print *, 'b ', itemp

    if (itemp /= 0) exit
  end do
  ibeta = itemp
  beta  = real(ibeta,O)
  it = 0
  b  = oner
  do

    it = it + 1
    b  = b * beta
    temp  = b + oner
    temp1 = temp - b

    print *, 'c ', temp1 - oner
    ! itemp = int (temp1 - oner)


    ! print *, 'c'
    if (itemp /= zeror) exit
  end do
  irnd  = 0
  betah = beta / twor
  temp  = a + betah
  if (temp - a /= zeror) irnd = 1
  tempa = a + beta
  temp  = tempa + betah
  if (irnd == 0 .and. temp - tempa /= zeror) irnd = 2
  negep  = it +3
  betain = oner / beta
  a = oner
  do i = 1, negep
    a = a * betain
  end do
  b = a
  do
    print *, 'd'

    temp = oner - a
    if (temp - oner /= zeror) exit
    a = a * beta
    negep = negep - 1
  end do
  negep  = - negep
  epsneg = a
  if (ibeta /= 2 .and. irnd /= 0) then
    a = (a * (oner + a)) / twor
    temp = oner - a
    if (temp - oner /= zeror) epsneg = a
  end if
  machep = -it - 3
  a = b
  do
    print *, 'e'

    temp = oner + a
    if (temp - oner /= zeror) exit
    a = a * beta
    machep = machep + 1
  end do
  eps  = a
  temp = tempa + beta * (oner + eps)
  if (ibeta /= 2 .and. irnd /= 0) then
    a = (a * (oner + a)) / twor
    temp = oner + a
    if (temp - oner /= zeror) eps = a
  end if
  ngrd = 0
  temp = oner + eps
  if (irnd == 0 .and. temp * oner - oner /= zeror) ngrd = 1
  i = 0
  k = 1
  z = betain
  t = oner + eps
  nxres = 0
  do
    y = z
    z = y * y
    a = z * oner
    temp = z * t
    if (a + a == zeror .or. abs(z) >= y) exit
    temp1 = temp * betain
    if (temp1 * beta == z) exit
    i = i + 1
    k = k + k
  end do
  if (ibeta /= 10) then
    iexp = i + 1
    mx   = k + k
  else
    iexp = 2
    iz   = ibeta
    do
      if (k < iz) exit
      iz   = iz * ibeta
      iexp = iexp + 1
    end do
    mx = iz + iz - 1
  end if
  do
    xmin = y
    y = y * betain
    a = y * oner
    temp = y * t
    if ( a + a == zeror .or. abs(y) >= xmin) exit
    k = k + 1
    temp1 = temp * betain
    if (temp1 * beta == y) then
      nxres = 3
      xmin  = y
      exit
    end if
  end do
  minexp = - k
  if (mx <= k + k - 3 .and. ibeta /= 10) then
    mx   = mx + mx
    iexp = iexp + 1
  end if
  maxexp = mx + minexp
  irnd   = irnd + nxres
  if (irnd == 2 .or. irnd == 5) maxexp = maxexp - 2
  if (irnd == 3 .or. irnd == 4) maxexp = maxexp - it
  i = maxexp + minexp
  if (ibeta ==2 .and. i == 0) maxexp = maxexp - 1
  if (i > 20) maxexp = maxexp - 1
  if (a /= y) maxexp = maxexp - 2
  xmax = oner - epsneg
  if (xmax * oner /= xmax) xmax = oner - beta * epsneg
  xmax = xmax / ( beta * beta * beta * xmin)
  i = maxexp + minexp + 3
  do j = 1, i
    if (ibeta == 2) then
      xmax = xmax + xmax
    else
      xmax = xmax * beta
    end if
  end do
end subroutine machr

0 个答案:

没有答案