【问题标题】:Fortran .AND. operator errorFortran .AND。操作员错误
【发布时间】:2015-04-13 23:31:10
【问题描述】:

我有一些包含以下行的 Fortran 代码:

IF((IFIX(X).AND.6).NE.0)
    THEN

X 的值是使用 NAMELIST 和 READ 语句指定的:

NAMELIST/XYZ/     ….,X,……
.
.
.
READ(5,XYZ)

变量 X 可以取以下值:

0.0
1.0
2.0
3.0
4.0
6.0

尝试使用 GCC Fortran (gfortran) 编译此程序(文件名 abcd.f),因此:

$gfortran -o abcd abcd.f

产生以下错误:

IF((IFIX(X).AND.6).NE.0)
                1
Error: Operands of logical operator '.and.' at (1) are INTEGER(4)/INTEGER(4)

我对 LOGICAL 变量和运算符的理解是,数值 0 转换为 FALSE,非零值转换为 TRUE。如果 .AND 的两个值。比较为 TRUE,则结果为 TRUE,否则结果为 FALSE。

因此,我想出了下面的值表:

X       IFIX(X)     IFIX(X).AND.6   (IFIX(X).AND.6).NE.0)   result

0.0     0 -> FALSE  FALSE -> =0     FALSE                   exit IF without executing THEN
1.0     1 -> TRUE   TRUE -> ≠0      TRUE                        execute THEN
2.0      2 -> TRUE  TRUE -> ≠0      TRUE                        execute THEN
3.0     3 -> TRUE   TRUE -> ≠0      TRUE                        execute THEN
4.0      4 -> TRUE  TRUE -> ≠0      TRUE                        execute THEN
6.0     6 -> TRUE   TRUE -> ≠0      TRUE                        execute THEN

因此,我认为逻辑没有任何错误(撇开这是否是实现预期结果的最佳方式的问题不谈 - 我正在处理我希望对其进行最少更改的遗留代码)。

谁能解释为什么我会收到此错误消息?

【问题讨论】:

    标签: fortran gfortran


    【解决方案1】:

    这种情况下的问题是.AND.的非标准使用在标准中,只有两个运算符都是LOGICAL时才定义这个;在你的情况下,它们都是INTEGER,这是编译器告诉你的。

    有几个问题需要注意:

    首先,您能否确定浮点值恰好是 0.0、1.0 等?如果它们不是通过设置变量而是通过具有潜在舍入误差的计算获得的,则结果可能是例如0.999999。然后IFIXINT 的一种古老形式)将向下取整,这可能是也可能不是预期的结果。

    其次,检查旧编译器的文档(如果仍然可用)或尝试按照程序的逻辑来了解.AND. 的非标准使用意味着什么。它的意思是逻辑还是位和(在 C 语言中,是&& 还是&)?如果它是按位的,则程序逻辑将与您上面概述的不同。您可以使用标准的 IAND 内在函数进行按位运算。

    【讨论】:

    • 谢谢 tkoenig。浮点值由用户在输入时指定,不计算。我会研究你提到的其他几点。
    【解决方案2】:

    IFIX大于1返回整数,小于1返回0。

    (X.EQV.0).NE.1 会做你想做的事吗?

    【讨论】:

    • 我认为最简单的解决方案是 IF(X.NE.0) THEN。两件事:(1)我想了解为什么会出现错误消息; (2) 这是 30,000 行程序的一部分,我不想破坏其他内容。我想一开始就想出这样一个错综复杂的结构一定有很好的理由。
    【解决方案3】:

    这个问题最终解决如下:

    LOGICAL IX,VAL0,VAL6
    .
    .
    .
    IX = IFIX(X)
    VAL0 = 0
    VAL6 = 6
    IF((IX .AND. VAL6) .NEQV. VAL0) THEN
    

    这看起来相当复杂且不必要,但它保留了原始代码的基本结构。它确实给出了有关从整数到逻辑的转换的警告消息,但它确实编译成功。

    这很好地说明了早期版本的 Fortran 中较为宽松的要求,而这些要求在后来的标准中得到了加强。

    感谢大家的建议。

    【讨论】:

      猜你喜欢
      • 2013-10-13
      • 2018-07-13
      • 1970-01-01
      • 2011-10-29
      • 2012-06-18
      • 2012-02-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多