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

发布于 2024-10-11 05:27:00 字数 670 浏览 3 评论 0原文

我正在重写一些代码,以便使用 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) 编译得很干净。

I'm rewriting some code to make a program compile with the gfortran compiler as opposed to ifort compiler I usually use. The code follows:

_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_ 

When I compile the above code using the gfortran compiler, I recieve this error:

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

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

All three of the variables coming into the subroutine are integers. I've looked around a bit and the gfortran wiki states that the gfortran compiler should be able to handle logical statments being applied to integer values. Several other sites I've visited either quote from the gnu wiki or agree with it. This is the first time I've seen this error as the Intel Fortran compiler (ifort) I normally use compiles cleanly.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

听闻余生 2024-10-18 05:27:00

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

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

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

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

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

.Or.两个 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

... 与 .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

-- .Or。在 Fortran 语言中

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

)。

The comments/answers above "may .Not. be" the correct responses, depending on your ultimate objective.

The likely purpose of that "WORD = .." statement is .NOT. to arrive at a boolean/logical result, but rather to obtain a kind of integer enumerator.

To see this, first "ignore" the bit shifting (iShift() etc), and just look at something like IntR = Int1 .Or. Int2. This will produce a "proper" integer result. The value will depend on not only the values of the int's, but also on their declared "type" (e.g. Integer(1), Integer(2), etc)

That is, the resulting value of WORD will be a "proper" integer; something like "33504" .. or whatever, (likely) .NOT. a 0/1 or -1/0 or .True./.False. etc

If you replace = Int1 .Or. Int2 with = (Int1 /= 0) .Or. (Int2 /= 0) ... you will get an "integer logical" (i.e. 0/1 etc) and WILL NOT produce the
desired enumerator ... if that is what you are looking for.

The .Or. on two Int's is a kind of bit-wise addition that produces a new num based on how the bits align/word size etc.

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

... similarly the .And. provides a kind of multiplication.

This technique is sometimes used to create enumerators somewhat like the use of powers of two (1,2,4,8...) are used to assign a value. Then, any sum of those
values can be decomposed, for example, into its constituent elements. For instance, if a(1) = 2, and a(2) = 8, then the sum 10 can be decomposed to
show the selections were the 1st and 4th elements of (1,2,4,8,...) etc.

It may help conceptualise this by noting that bit-shifting is like multiplying by 2 (for left shift) and dividing by 2 (for right shift).

BTW, you don't need to restrict to Fortran for this. Whack it into a VBA function and see the result in your spreadsheet VBA does not
have bit shift intrinsics, but they are available ... in any case it will demonstrate the Int1 .Or. Int2 behaviour even without bit shifting, such as

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

-- .Or. in Fortran

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

).

捎一片雪花 2024-10-18 05:27:00

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

It is not standard Fortran to apply logical/boolean operators to integer variables. If the goal is a boolean result, the ideal solution would be to convert the types to logical. If, as it appears from casual examination, the code is really doing bit-wise operations, then it would be better to use the IAND and IOR intrinsic functions.

单身情人 2024-10-18 05:27:00

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 。

gfortran is expecting booleans for the logical operators and the code is providing integers. Use comparisons with zero instead of logical operators.

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

gfortran and ifort use different representations for .true. and .false. values, so it's best to stick to booleans when that's what the code needs. In a conversion from ifort to gfortran I got bit by the former representing .true. as -1 and the latter using 1 for the same purpose, instead of the traditional (C-like) not 0.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文