我有一些包含以下行的Fortran代码:
IF((IFIX(X).AND.6).NE.0)
THEN
使用NAMELIST和READ语句指定X的值:
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
所以,我没有看到逻辑上的任何错误(撇开这是否是实现预期结果的最佳方法的问题 - 我正在处理遗留代码,我希望对其进行最少的更改)。
任何人都可以解释为什么我收到此错误消息吗?
答案 0 :(得分:0)
IFIX如果大于1则返回整数,如果小于1则返回0。
(X.EQV.0).NE.1会做你想要的吗?
答案 1 :(得分:0)
这种情况下的问题是.AND.
的非标准使用在标准中,只有当两个运算符都是LOGICAL
时才会定义;在你的情况下,它们都是INTEGER
,这是编译器告诉你的。
有几个需要注意的问题:
首先,你能确定浮点值正好是0.0,1.0 ......等等吗?如果它们不是通过设置变量获得的,而是通过具有潜在舍入误差的计算获得的,则结果可能是例如0.999999。然后IFIX
(INT
的古老形式)将向下舍入,这可能是也可能不是预期的。
其次,检查旧编译器的文档(如果仍然可用)或尝试遵循程序的逻辑,以了解.AND.
的非标准使用的含义。它的意思是逻辑还是按位(用C语言来说,是&&
还是&
)?如果它是按位的,程序逻辑将与您在上面概述的不同。您可以使用标准IAND
内在函数进行按位运算。
答案 2 :(得分:0)
这个问题最终解决如下:
LOGICAL IX,VAL0,VAL6
.
.
.
IX = IFIX(X)
VAL0 = 0
VAL6 = 6
IF((IX .AND. VAL6) .NEQV. VAL0) THEN
这似乎相当复杂和不必要,但它保留了原始代码的基本结构。它确实给出了关于从整数到逻辑的转换的警告消息,但它确实成功编译。
这很好地说明了早期版本的Fortran中较为宽松的要求,这些要求在后来的标准中得到了加强。
感谢大家的建议。