如何使用gfortran处理应用于整数值的逻辑语句?

时间:2011-01-06 22:04:08

标签: fortran intel gfortran

我正在重写一些代码,使用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)干净利落地编译。

3 个答案:

答案 0 :(得分:3)

根据您的最终目标,上面的评论/答案“可能。不会是”正确答案。

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

要看到这一点,首先“忽略”位移(iShift()等),然后看看像IntR = Int1 .Or这样的东西。 INT2。这将产生“适当的”整数结果。该值不仅取决于int的值,还取决于它们声明的“type”(例如Integer(1),Integer(2)等)

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

如果你替换= Int1。或者。 Int2 with =(Int1 / = 0)。或者。 (Int2 / = 0)...你会得到一个“整数逻辑”(即0/1等)并且不会产生 期望的普查员...如果这就是你要找的。

。或者。在两个Int上是一种逐位加法,它根据位对齐/字大小等方式产生一个新的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

...同样的。和。提供了一种乘法。

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

通过注意位移是乘以2(左移)和除以2(右移),可能有助于概念化。

顺便说一下,你不需要为此限制Fortran。把它放到VBA函数中,看看你的电子表格中的结果VBA没有 有点移位内在函数,但它们是可用的...无论如何它将演示Int1。或者。 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

)。

答案 1 :(得分:2)

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

答案 2 :(得分:0)

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

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

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