Fortran语言中的浮点算法

Fortran语言中的浮点算法,fortran,Fortran,我继承了一些我试图理解的Fortran代码。它在很多地方使用实际变量,我认为,它不应该是这样的,但是也许我误解了FORTRAN中的工作原理(与我更熟悉的C++相比),因此这个问题。 因此,所讨论的变量本质上是“分类值”、“因子”或“枚举”,这取决于您如何看待/想要调用它。它们是数据类型REAL,只能接受有限数量的预定义整数值。所以说变量a只能是值1、2或3。这些值从外部文件中读取;在这些外部文件中,它们表示为整数,因此不存在“外部数据源中的舍入问题”之类的情况 然而,在代码中,它从不进行直接比较

我继承了一些我试图理解的Fortran代码。它在很多地方使用实际变量,我认为,它不应该是这样的,但是也许我误解了FORTRAN中的工作原理(与我更熟悉的C++相比),因此这个问题。 因此,所讨论的变量本质上是“分类值”、“因子”或“枚举”,这取决于您如何看待/想要调用它。它们是数据类型REAL,只能接受有限数量的预定义整数值。所以说变量a只能是值1、2或3。这些值从外部文件中读取;在这些外部文件中,它们表示为整数,因此不存在“外部数据源中的舍入问题”之类的情况

然而,在代码中,它从不进行直接比较,总是进行大于/小于检查。因此,与其这样做

if (a == 1) then
是的

if (a > 0.9 .and. a < 1.1) then
如果(a>0.9.和.a<1.1),则
您可以想象,这会让人非常困惑/厌烦,尤其是当需要检查某个值是否属于多个类别时

所以我认为这是一种情况,有人在某种程度上听到“从不比较实值”(由于存储浮点值的有限精度的性质,每个编程语言中都存在同样的问题),但当时并不真正理解这一点(我猜第一个错误是分类值应该表示为整数值,但目前的情况就是这样)

也许我只是误解了实数和整数值是如何在Fortran中表示和工作的?有没有可能出现这样的情况

b = 1.5
a = REAL(INT(b))

if (a > 0.9 .and. a < 1.1) then
b=1.5
a=实(INT(b))
如果(a>0.9.和.a<1.1),则

有意义吗?

只有在不使用实际值执行任何操作的情况下(只需指定一个值并将相等性与指定的相同文字、相同种类的参数进行比较),才不需要公差

问题是,对于实变量a,例如:

Real a
a = 2
你可以肯定

a == 2
将始终为
.true.
。但例如,对于由b表示的另一个实值:

a  / b * b == 2

(或任何其他操作)不保证为.true。

只有在不使用实值执行任何操作的情况下(只需指定一个值并将相等性与指定的相同文字、相同种类的参数进行比较),才不需要公差

问题是,对于实变量a,例如:

Real a
a = 2
你可以肯定

a == 2
将始终为
.true.
。但例如,对于由b表示的另一个实值:

a  / b * b == 2

(或任何其他操作)不保证为.true。

如果出于某种原因变量必须保持为实,则可以使用 比较中的内在Fortran函数NINT(最接近的整数):

if( nint(a) == 1 ) then 
....

如果出于某种原因,变量必须保持为实,则可以使用 比较中的内在Fortran函数NINT(最接近的整数):

if( nint(a) == 1 ) then 
....

你是对的:“永远不要在没有公差的情况下比较实数。”IEEE浮点数不能是精确的。你不能用二进制表示0.1,也不能用十进制表示1/3。FORTRAN中的实数是IEEE浮点数;与整数非常不同。FORTRAN的实数遵循模型形式
s*b^e*\sum{k=1}{p}f\k*b^{-k}
了解一些参数(请参阅);整数建模类似。也许我的问题表达得不够清楚-我的意思是,如果我只把整数值放在实数中,它们可以与==?@Roel进行比较吗?是的,你可以使用==。如果你有一个实数变量,它可能是一个32位的实体,精度为24位,所以你可以与一个高达2^24的整数值进行比较。如果您有一个双精度变量,它可能是一个精度为53位的64位变量。对于双精度,您可以比较高达2^53的相等值。为什么?因为这些范围内的整数可以用浮点格式精确表示。如果变量在逻辑上只接受某一组离散的预定义值,然后它绝对应该有一个包含这些限制的类型——至少是整数,如果FORTRAN有,它应该有一个实际的枚举类型。你是对的:“永远不要在没有公差的情况下比较实数。”IEEE浮点数不能是精确的。用二进制表示0.1比用十进制表示1/3更准确。FORTRAN中的实数是IEEE浮点数;与整数非常不同。对于某些参数,FORTRAN的实数遵循模型形式
s*b^e*\sum{k=1}{p}f_k*b^{-k}
(请参阅);整数建模类似。也许我的问题表达得不够清楚-我的意思是,如果我只把整数值放在实数中,它们可以与==?@Roel进行比较吗?是的,你可以使用==。如果你有一个实数变量,它可能是一个32位的实体,精度为24位,所以你可以与一个高达2^24的整数值进行比较。如果您有一个双精度变量,它可能是一个精度为53位的64位变量。对于双精度,您可以比较高达2^53的相等值。为什么?因为这些范围内的整数可以用浮点格式精确表示。如果变量在逻辑上只接受某一组离散的预定义值,那么它绝对应该有一个包含这些限制的类型——至少是整数,如果FORTRAN有,它应该有一个实际的枚举类型。甚至不是-1.0==1.0?也许我确实误解了浮点表示法;它怎么能变成尾数1和指数0表示的值以外的任何东西呢?不能全部(足够小)整数可以用指数为0的浮点数来精确表示,加减运算不也总是精确的吗在一般情况下不能保证。是的,肯定有一组值