我正在重写一些代码,使用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)干净利落地编译。
答案 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等)并且不会产生 期望的普查员...如果这就是你要找的。 p>
。或者。在两个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
。