如果文件中(而不是模块中)具有独立的函数,并且以单精度调用它,而它期望双精度数:
main.f90:
program main
call test(1.0)
end program main
test.f90:
subroutine test(a)
double precision :: a
print *, "a", a
end subroutine
在这种情况下,编译器如何从单精度“转换”为双精度? 使用浮点格式,我希望这些位在强制转换期间保持不变,但会附加附加零。那就是:
1 = 0 01111111 00000000000000000000000 in single-precision
,我希望最终值为2 ^(-7):
0 01111111000 0000000000000000000000000000000000000000000000000000 in double precision
令人惊讶的是,对于gfortran 6.4.0,最终值为5.2635442471208903E-315。
答案 0 :(得分:3)
编译器不强制转换。您写的不是Fortran。
在主程序中,子例程test
具有隐式接口。本质上,编译器对此是一无所知,只是它是一个子例程。您还告诉它它只有一个(默认)实参。
在引用子例程时提供正确的类型和类型的参数是您的责任,而不是编译器的责任。您在此处失败,因此没有兼容的Fortran程序。 Fortran编译器不欠您任何费用。
您将观察到的内容将取决于Fortran处理器的实现细节。该子例程需要一个双精度参数,并且没有理由相信它还有其他内容。不管有复制/复制输出还是某些地址通过 1 ,内存的解释都将不匹配。在哑元参数中,除与实际参数的默认实数对应的字节以外的所有字节均为“垃圾”。
如果在主程序中为子例程提供显式接口,则仍然不会进行强制转换,但是编译器会注意到不匹配。同样,即使存在隐式接口,某些编译器(可能带有某些编译标志)也会进行一些检查。
1 有关可能通过引用的详细信息,请参见user5713492的注释。
答案 1 :(得分:-2)
我猜编译器会根据字节顺序“广播”。如果您在左侧插入零,则会得到:
0 00000000000 0000000000000000000000111111100000000000000000000000
哪个是5.2635442471208903E-315。您可以在编译时通过强制字节序进行检查。