Fortran 中内函数fraction() 的输出错误

问题描述 投票:0回答:4

例如,我不明白 FRACTION() 的输出

write(*,*) fraction(553.334)

它给了我

0.5403652

我认为它应该返回

0.334
,就像
553.334-floor(553.334)
一样。我的理解有什么问题吗?

floating-point fortran
4个回答
8
投票

相反,该值正是(在可用精度范围内)正确的答案。 我认为错误在于您误解了

fraction
的作用。 解释一下该标准(在网上广泛提供,许多教程和其他指南也是如此)
fraction(x)
返回x
模型表示
的小数部分。 在大多数现代计算机上,
x
的模型表示形式是
x*2^-k
形式的数字。实际上,该函数返回数字
x
除以下一个最高的 2 次幂,在您的示例中为
553.034/1024 == 553.034*2^-10

与计算领域一样,RTFM(阅读 Fortran 手册)。


7
投票

fraction()
并没有像你想象的那样做。它返回型号的小数部分(以 2 为底)。因此,对于您的示例,它正在返回:

553.334/1024 = 0.5403652

一如既往,如有疑问,请阅读文档


1
投票

快速解决方法:

real(kind(1.d0)) elemental function fractional_part(x)  !Double precision
  real(kind(1.d0)),intent(IN)::x

  fractional_part=x-floor(x)

end function fractional_part

如果您想将其用作重载模块过程,您可以使用新的“内在”来查找 real(4)、real(8) 和 real(16)(如果支持)的小数部分。


-2
投票

标准中的描述是“fraction(x)返回x的小数部分”。 但WG5标准中的示例是fraction(3.0) -> 0.75,这与set_exponent(x,0)相同。

所以,自 Fortran 95 以来的所有标准中的简短描述都是错误的。 实际操作与set_exponent(x,0)相同。

我认为 WG5 for Fortran 2020 的适当操作是将“fraction(x)”定义为 x-floor(x),用于类型为 real(4)、real(8) 和 real(16)(如果支持)的参数,并注意,对于 i=0,set_exponent(x,i) 已经提供了混乱且混乱的结果。 如果这已经是真的,请修复文档。

© www.soinside.com 2019 - 2024. All rights reserved.