我有一个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