我在FORTRAN编写了一个程序,它是一个简单的乘法程序。它似乎在一台计算机上工作正常(编译没有警告和输出是正确的),但是当我将文件夹scp到另一台计算机时,它编译没有警告但是,输出更改为随机数,不知道为什么这是?有两个输出,一个是递归算法,另一个是迭代完成。递归工作正常,但迭代给出错误。我已经运行make clean,我也尝试将文件夹更改为一个新的干净文件夹,仍然是同样的问题。
它正常工作的版本:GNU Fortran(Debian 4.9.2-10)4.9.2
输出错误的版本:GNU Fortran(Debian 4.4.5-8)4.4.5
program multiplication
integer(kind = 8) :: multiplier, multiplicand, rcursvmultply, itratvmultply
write(*,*) "multiplier?"
read(*,*) multiplier
write(*,*) "multiplicand?"
read(*,*) multiplicand
write(*,*) rcursvmultply(multiplier, multiplicand)
write(*,*) itratvmultply(multiplier, multiplicand)
end program
recursive function rcursvmultply(multiplier, multiplicand) result(answer)
integer(kind = 8), intent(in) :: multiplier, multiplicand
integer(kind = 8) :: answer
if (multiplier == 0) then
answer = 0
else if (multiplier == 1) then
answer = multiplicand
else if ((multiplier > 1) .and. (mod(multiplier, 2) == 0)) then
answer = rcursvmultply((multiplier/2), (multiplicand*2))
else if ((multiplier > 1) .and. (mod(multiplier, 2) == 1)) then
answer = (multiplicand + (rcursvmultply((multiplier/2), (multiplicand*2))))
end if
end function rcursvmultply
integer(kind = 8) function itratvmultply(multiplier, multiplicand)
integer(kind = 8) :: multiplier, multiplicand
do while (multiplier > 0)
if ((mod(multiplier, 2)) == 1) then
itratvmultply = (multiplicand + itratvmultply)
end if
multiplier = multiplier/2
multiplicand = multiplicand*2
end do
end function itratvmultply
我还在计算机上收到以下警告:
make: Warning: File `Makefile' has modification time 4.6 s in the future
make: warning: Clock skew detected. Your build may be incomplete.
对于上面的警告,我已经在原来的计算机和scp上做了干净,之后它似乎没有摆脱它。但是,当我清理它时,它不会再在该计算机上产生警告。我不确定为什么会这样。
答案 0 :(得分:2)
itratvmultply
itratvmultply = (multiplicand + itratvmultply)
首先执行结果变量(即itratvmultply
)不保证具有任何特定值;它尚未明确分配给。这意味着赋值的 rhs 实际上是垃圾。
如果在一台计算机上(使用一个版本的编译器和一个未知的(对我们)编译选项集),您报告的症状是完全可解释的,编译器将值设置为0
而在另一台计算机上(不同)编译器版本,可能是不同的选项)没有提供这样的值,变量可以获得恰好是位和字节的任何内容。
您可能认为编译器在程序启动时将变量设置为0
。 Fortran语言标准无法保证这一点。低级优化的编译器通常会在程序启动时将变量设置为0
,但在较高级别则不会。
要解决这个问题,请包括
行 itratvmultply = 0
在代码第一次出现在赋值的 rhs 之前的代码中。并查看编译器的文档,了解如何使用它来警告您使用未初始化的变量。
@ TriskalJM的评论回答了你关于制作过程中有趣的未来主义的问题。