gfortran如何处理整数与实数的幂运算?我一直以为是相同的,但请考虑示例:
program main
implicit none
integer, parameter :: dp = selected_real_kind(33,4931)
real(kind=dp) :: x = 82.4754500815524510_dp
print *, x
print *, x**4
print *, x**4.0_dp
end program main
使用gfortran进行编译会得到
82.4754500815524510000000000000000003
46269923.0191143410452125643548442147
46269923.0191143410452125643548442211
现在显然这些数字几乎是一致的-但是,如果gfortran以相同的方式处理整数和实数以求幂,我希望它们是相同的。有什么作用?
答案 0 :(得分:5)
略微扩展程序可以显示正在发生的事情:
ijb@ianbushdesktop ~/work/stack $ cat exp.f90
program main
implicit none
integer, parameter :: dp = selected_real_kind(33,4931)
real(kind=dp) :: x = 82.4754500815524510_dp
print *, x
print *, x**4
print *,(x*x)*(x*x)
print *,Nearest((x*x)*(x*x),+1.0_dp)
print *, x**4.0_dp
end program main
编译和运行可以得到:
ijb@ianbushdesktop ~/work/stack $ gfortran --version
GNU Fortran (GCC) 7.4.0
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
ijb@ianbushdesktop ~/work/stack $ gfortran exp.f90
ijb@ianbushdesktop ~/work/stack $ ./a.out
82.4754500815524510000000000000000003
46269923.0191143410452125643548442147
46269923.0191143410452125643548442147
46269923.0191143410452125643548442211
46269923.0191143410452125643548442211
ijb@ianbushdesktop ~/work/stack $
因此
看起来编译器很聪明,可以算出可以通过乘法来完成整数幂运算,这比一般的幂运算要快得多
使用通用幂函数与乘法答案仅相差1位。鉴于我们不能说本身更为准确,因此我们必须接受两者都一样准确
因此,总的来说,编译器会在可能的情况下使用简单的乘法运算,而不是使用完整的幂运算程序,但是即使必须使用更昂贵的路由,编译器也会给出相同的答案,以供仔细考虑“相同”一词的含义>
答案 1 :(得分:1)
为了完整性,对(精确)分数求幂会导致
46269923.019114341045212564354844220930226304938209797955723262974801
46269923.0191143410452125643548442211 is the nearest
46269923.0191143410452125643548442147
对最接近的四倍精度浮点(https://en.wikipedia.org/wiki/Quadruple-precision_floating-point_format)求幂会导致
46269923.01911434104521256435484422112355946434320203876355837024902939447201788425445556640625
46269923.0191143410452125643548442211 does fit
因此,求幂函数似乎四舍五入到最近的浮点数。我不知道是运气还是底层的数学库保证了正确的舍入。
整数指数:
x2 = x*x
x4 = x2*x2
累积两个四舍五入错误,所以可能是1 ulp off,这并不奇怪。