【发布时间】:2018-11-14 23:46:52
【问题描述】:
我继承了一些我试图理解的 Fortran 代码。它在许多地方使用 REAL 变量,我认为它不应该 - 但也许我误解了它在 Fortran 中的工作原理(与我更熟悉的 C++ 相比),因此这个问题。
因此,所讨论的变量本质上是“分类值”、“因素”或“枚举”,具体取决于您如何看待/想要称呼它。它们的数据类型为 REAL,只能采用有限数量的预定整数值。所以说变量a只能是1、2或3。这些值是从外部文件中读取的;在这些外部文件中,它们表示为整数,因此不是“外部数据源中的舍入问题”之类的情况。
但是在代码中,它从不进行直接比较,总是进行大于/小于检查。所以,而不是做
if (a == 1) then
确实如此
if (a > 0.9 .and. a < 1.1) then
您可以想象这会变得非常混乱/令人厌烦,尤其是当它需要检查一个值是否是多个类别之一时。
所以我认为这是一种情况,有人在某些时候听到“从不比较 REAL 值”(由于存储浮点值的有限精度的性质,每个编程语言都存在同样的问题),但后来没有' 真的不明白什么时候适用(我猜第一个错误是分类值应该表示为整数值,但现在情况就是这样)。
OTOH 也许我只是误解了 REAL 和 INTEGER 值在 Fortran 中是如何表示和工作的?会不会有这样的情况
b = 1.5
a = REAL(INT(b))
if (a > 0.9 .and. a < 1.1) then
有意义吗?
【问题讨论】:
-
你是对的:“永远不要在没有公差的情况下比较实数。” IEEE 浮点数不能准确。用二进制表示 0.1 不能比用十进制表示 1/3。 FORTRAN 中的实数是 IEEE 浮点数;与整数非常不同。
-
Fortran的实数遵循模型形式
s*b^e*\sum_{k=1}^{p}f_k*b^{-k}的一些参数(见here);整数建模类似。 -
也许我的问题表述不够清楚 - 我的意思是,如果我只将整数值放入实数中,它们可以与 == 进行比较吗?
-
@Roel,是的,您可以使用 ==。如果您有一个 REAL 变量,它可能是一个具有 24 位精度的 32 位实体,因此您可以将相等性与最大为 2^24 的整数值进行比较。如果你有一个 DOUBLE PRECISION 变量,它可能是一个 64 位的 53 位精度的变量。对于 DOUBLE PERCISION,您可以比较高达 2^53 的相等性。为什么?因为这些范围内的整数完全可以用浮点格式表示。
-
如果变量在逻辑上应该只取一组离散的、预定义的值,那么它绝对应该有一个体现这些限制的类型——至少是整数, 和一个实际的枚举类型(如果 FORTRAN 有它们)。
标签: fortran