type-conversion - Fortran 数值运算中自动种类/类型转换的可移植性
问题描述
根据 Fortran 标准,如果数值运算的操作数具有不同的数据种类/类型,则结果值具有由具有更高十进制精度的操作数确定的种类/类型。在计算运算之前,先将具有较低小数精度的操作数转换为较高精度的种类/类型。
现在,使用高精度数据种类/类型意味着一定程度的有效数字是准确的,但种类/类型转换似乎并不能保证这样的事情1。出于这个原因,我避免混合单精度和双精度实数。
但这是否意味着应该不惜一切代价避免自动类型/类型转换?例如,我会毫不犹豫地写出和x = y**2
都是实数(同类),但指数是整数。x
y
让我们将这个问题的范围限制在两个操作数之间的单个操作的结果上。我们没有考虑在多个值之间进行运算的方程的结果,而其他问题可能会出现。
让我们也假设我们正在使用可移植的类型/种类系统。例如,在下面的代码中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.2000000000000000d0
而是变为类似的东西1.200000047683758d0
。这实际上有多重要可能取决于应用程序。
解决方案
推荐阅读
- python - 用于可视化循环 ETA 的进度条
- bash - bash 如何处理不匹配的通配符?
- azure-devops - 在 Azure DevOps 中显示上周的项目
- node.js - 错误:在 window10 上找不到模块“../lib/utils/unsupported.js”
- python - 如何使用熊猫格式化excel单元格?
- python - /password-reset/ 处的 ConnectionRefusedError [WinError 10061] 无法建立连接,因为目标计算机主动拒绝它
- linux - 在低内存嵌入式系统中使用 Busybox 有什么意义
- python - 如何将列表中的空项目更改为 N/a 值?
- hl7-fhir - 从 EHR 中提取 QDM 元素以计算 eCQM
- javascript - 如何使用 json 将 base64 url 数据从 javascript 客户端发送到使用 websocket 的 nodejs 服务器?