Fortran 中数值运算中自动类型/类型转换的可移植性

Portability of auto kind/type conversions in numerical operations in Fortran

提问人:Matt P 提问时间:7/23/2020 最后编辑:Matt P 更新时间:7/23/2020 访问量:102

问:

根据 Fortran 标准,如果数值运算的操作数具有不同的数据类型,则结果值具有由操作数确定的类型/类型,具有更高的十进制精度。在计算操作之前,首先将具有较低十进制精度的操作数转换为精度较高的 kind/type。

现在,使用高精度数据类型/类型意味着对有效数字的一定水平具有准确性,但类型/类型转换似乎并不能保证这些事情1。出于这个原因,我避免混合使用单精度和双精度实数。

但是,这是否意味着应该不惜一切代价避免自动类型/类型转换?例如,我会毫不犹豫地写出 where both 和 are reals(同一种),但指数是一个整数。x = y**2xy

让我们将这个问题的范围限制在两个操作数之间的单个操作的结果。我们不考虑在多个值之间进行运算的方程的结果,而其他问题可能会悄悄出现。

我们还假设我们正在使用便携式类型/种类系统。例如,在下面的代码中用于定义分配给双精度实值的种类。selected_real_kind

然后,我有两个关于在两个操作数之间进行类型/种类转换的数值表达式的问题:

  • 在实践中,它是“便携式”的吗?对于使用来自不同编译器的自动类型/种类转换的操作,我们是否可以期望相同的结果?

  • 如果较低精度的操作数仅限于整数或整数实数,它是否“准确”(和“可移植”)?为了清楚这一点,我们是否可以总是假设,对于所有编译器?如果是这样,那么我们是否可以总是假设简单的表达式(例如)是真的,因此转换既准确又可移植?0==0.0d0, 1==1.0d0, 2==2.0d0, ... (1 - 0.1230d0) == (1.0d0 - 0.1230d0)

举个简单的例子,从整数到双精度实数的自动转换(如下面的代码所示)是否准确和/或可移植?

program main
  implicit none
  integer, parameter :: dp = selected_real_kind(p=15)
  print *, ((42 - 0.10_dp) == (42.0_dp - 0.10_dp))    
end program

我已经使用 gfortran 和 ifort 进行了测试,使用不同的操作数和运算,但只要我将转换限制为整数或整数实数,还没有看到任何引起关注的内容。我在这里遗漏了什么,还是只是透露了我的非 CS 背景?


1例如,根据这些英特尔 Fortran 文档,转换为实数类型的整数具有用零填充的小数。对于单精度实数到更高精度实数的转换,首先将转换后的高精度操作数的低阶位设置为零,以填充额外的小数位。因此,例如,当具有非零小数部分(例如 1.2)的单精度实操作数转换为双精度时,转换不会自动提高值的精度 - 例如,1.2 不会变成 1.200000000000000000d0,而是变成类似于 1.2000000047683758d0 的东西。 这实际上有多重要可能取决于应用程序。

类型转换 Fortran 精度

评论

0赞 francescalus 7/23/2020
“没有小数小数成分的数字可以用二进制精确表示”是不正确的,至少如果“二进制”是指基数 2 浮点数。(此外,该标准不要求使用基数 2 浮点数,并允许基数 2 浮点具有非常小的量级整数,不能完全表示。您追求什么级别的保证?“标准严格要求”、“如果发生其他事情,你应该感到震惊”、“更有可能”?另请注意,Fortran 标准不支持期望不同编译器的结果通常完全相同。
0赞 Matt P 7/23/2020
@francescalus 哈 - 我不认为我期望结果在总体上总是完全相同,但编写可移植代码的整个概念似乎是目标,以便人们可以达到“如果发生其他事情时感到震惊”的水平。为了改进我的示例代码,您是建议还是只是?selected_real_kindkind(0.d0)
0赞 evets 7/23/2020
整数值可以完全表示为浮点值,前提是整数值的大小小于浮点实体的精度。例如,对于 IEEE-754 binary32,.如果 ,则 的转换是完全可表示的。如果 ,则转换可能是精确的,但取决于尾随位是否为零。2**ppp = 24iabs(i) < 2**piiabs(i) > 2**pi
0赞 Matt P 7/23/2020
@evets 这是一个很好的观点 - 谢谢。这有助于建立信心,即某些类型的转换或多或少是值得信赖的,即使没有要求特定结果的标准。
0赞 Matt P 7/23/2020
更新:我采纳了@francescalus的建议并更改了示例代码,以便它使用而不是来自。由于此问题讨论的是精度,因此此更改是有道理的。selected_real_kindreal64iso_fortran_env

答: 暂无答案