2

我正在重写一些代码以使用 gfortran 编译器编译程序,而不是我通常使用的 ifort 编译器。代码如下:

_Subroutine SlideBits (WORD, BITS, ADDR) 

Implicit None  
Integer(4) WORD  
Integer(4) BITS  
Integer(4) ADDR  
Integer(4) ADDR1 

ADDR1 = 32 - ADDR  
WORD = (WORD .And. (.Not.ISHFT(1,ADDR1))) .Or. ISHFT(BITS,ADDR1)  

End_ 

当我使用 gfortran 编译器编译上述代码时,我收到此错误:

WORD = (WORD .And. (.Not.ISHFT(1,ADDR1))) .Or. ISHFT(BITS,ADDR1) 

Error: Operand of .NOT. operator at (1) is INTEGER(4)  

进入子程序的所有三个变量都是整数。我环顾四周,gfortran wiki 指出 gfortran 编译器应该能够处理应用于整数值的逻辑语句。我访问过的其他几个站点要么引用了 gnu wiki,要么同意它。这是我第一次看到这个错误,因为我通常使用的英特尔 Fortran 编译器 (ifort) 编译干净。

4

3 回答 3

3

上面的评论/答案“可能。不是”是正确的回答,这取决于您的最终目标。

“WORD = ..”语句的可能目的是 .NOT。获得布尔/逻辑结果,而是获得一种整数枚举器。

要看到这一点,首先“忽略”位移(iShift() 等),然后只看 IntR = Int1 .Or 之类的东西。诠释2。这将产生一个“正确的”整数结果。该值不仅取决于 int 的值,还取决于它们声明的“类型”(例如 Integer(1)、Integer(2) 等)

也就是说,WORD 的结果值将是一个“正确的”整数;像“33504”..或其他什么,(可能).NOT。0/1 或 -1/0 或 .True./.False。ETC

如果您替换 = Int1 .Or。Int2 与 = (Int1 /= 0) . 或。(Int2 /= 0) ...您将得到一个“整数逻辑”(即 0/1 等)并且不会产生所需的枚举数...如果这是您正在寻找的。

. 或。on two Int's 是一种按位加法,它根据位对齐/字长等方式产生一个新的 num。

e.g. 3 == 011, 2 = 010 ... so, 3 .Or. 2 ==> 011 = 3
e.g. 3 == 011, 5 = 101 ... so, 3 .Or. 5 ==> 111 = 7
e.g. 5 == 101, 5 = 101 ... so, 5 .Or. 5 ==> 101 = 5

......同样的.And。提供一种乘法。

这种技术有时用于创建枚举器,有点像使用 2 的幂 (1,2,4,8...) 来分配值。然后,可以将这些值的任何总和分解为例如其组成元素。例如,如果 a(1) = 2 且 a(2) = 8,则总和 10 可以分解以显示选择是 (1,2,4,8,...) 的第 1 个和第 4 个元素等等

通过注意位移就像乘以 2(对于左移)和除以 2(对于右移)可能有助于概念化这一点。

顺便说一句,您不需要为此限制为 Fortran。将其敲入 VBA 函数并在电子表格中查看结果 VBA 没有位移内在函数,但它们是可用的......无论如何它都会演示 Int1 .Or。即使没有位移,也可以进行 Int2 行为,例如

Function TwoIntsOr(Int1 As Long, Int2 As Long) As Long
    '
    TwoIntsOr = Int1 Or Int2
    '
End Function

- 。或者。在 Fortran 中

Function TwoIntsOr(Int1, Int2)
    Integer     :: TwoInstOr
    Integer, Intent(In) :: Int1, Int2
    !
    TwoIntsOr = Int1 .Or. Int2
    !
End Function

)。

于 2014-01-21T22:05:55.377 回答
2

将逻辑/布尔运算符应用于整数变量不是标准的 Fortran。如果目标是布尔结果,理想的解决方案是将类型转换为逻辑类型。如果从不经意的检查中可以看出,代码确实在执行按位运算,那么最好使用 IAND 和 IOR 内部函数。

于 2011-01-06T22:50:40.103 回答
1

gfortran 期待逻辑运算符的布尔值,并且代码提供整数。使用与零的比较而不是逻辑运算符。

WORD = ((WORD /= 0) .And. (ISHFT(1,ADDR1) == 0)) .Or. (ISHFT(BITS,ADDR1) /= 0)

gfortran 和 ifort 对.true..false.值使用不同的表示形式,因此最好在代码需要时坚持使用布尔值。在从 ifort 到 gfortran 的转换中,我被前者表示.true.为 -1 而后者出于相同目的使用 1 而不是传统的 (C-like) not 0

于 2011-01-06T22:26:28.680 回答