TRUE 的数值等价是 -1?
Numerical equivalent of TRUE is -1?
我在 Visual Studio 2012 年使用 Intel Fortran 编译 Fortran 代码。
当我尝试使用逻辑运算符时,我注意到独立的逻辑表达式会按预期产生 T 或 F。但是,如果我需要数字 T 或 F(0 或 1),当逻辑结果为 T 时我会得到 -1。
例如:
integer*4 a
a = 1
logicval = (node(5,L).gt.0)
numval = 1*(node(5,L).gt.0)
write(*,*) logicval, numval
会输出
T, -1
有什么方法可以重新定义分配给 T & F 的数值?
是的,这是预期的 Intel Fortran 的 TRUE 确实是 -1,因为所有位都设置为 1。
此外,您将整数用作逻辑(布尔)变量是完全不规范的。你应该让你的代码长几行并且总是做正确的转换。你的 integer_var = 1*(node(5,L).gt.0)
在 Fortran 中是不允许的,它 将被许多编译器拒绝。如果您删除 1*
gfortran 将发出警告,但您的表单会导致错误。
您可以简单地以符合标准的方式转换您的逻辑值和整数
if (l) then
x = 1
else
x = 0
end if
您可以使用 MERGE()
内部函数或使用 WHERE
.
轻松地将 Fortran 逻辑数组转换为包含 1 和 0 的整数数组
英特尔 Fortran 的一个简单修复可能是 -fpscomp logicals
英特尔 Fortran,它将 LOGICAL
类型的处理切换为将任何非零值视为 true 并使 .true.
常量等效到整数 1.
仍然要小心,因为它不会使您的程序具有可移植性,它只能解决特定编译器中的一个可移植性问题。
您可以使用 C 互操作逻辑类型来将定义与 Intel C 表示相匹配:
use iso_c_binding
logical(c_bool) :: variable
按照 C99 对 _Bool 的规定,这些将具有 +1 和 0 的值。如果您需要它们与 int
互操作,您必须进行一些简单的转换。 C_int
与 c_bool
不兼容。
根据英特尔编译器的版本,您可能需要使用 -standard-semantics
(或 -fpscomp logicals
)以获得正确的 logical(c_bool)
。我认为这是非常不幸的。
正如其他人所说,对于这种非标准用法,Intel Fortran 的默认设置是设置了低位(奇数)的整数值为真,偶数值(低位清除)为假。常数.TRUE。具有 -1 的位模式。当您进行转换时,它会变得更加复杂,直到版本 17,编译器在这方面还没有完全一致。请注意,如果您使用 -standard-semantics,则隐含 -fpscomp 逻辑。
请阅读 https://software.intel.com/en-us/forums/intel-visual-fortran-compiler-for-windows/topic/275071#comment-1548435 and also the version 17 release notes (https://software.intel.com/en-us/articles/intel-fortran-compiler-170-release-notes) 以了解该版本中数字-逻辑转换处理方式的变化信息。
我在 Visual Studio 2012 年使用 Intel Fortran 编译 Fortran 代码。 当我尝试使用逻辑运算符时,我注意到独立的逻辑表达式会按预期产生 T 或 F。但是,如果我需要数字 T 或 F(0 或 1),当逻辑结果为 T 时我会得到 -1。
例如:
integer*4 a
a = 1
logicval = (node(5,L).gt.0)
numval = 1*(node(5,L).gt.0)
write(*,*) logicval, numval
会输出
T, -1
有什么方法可以重新定义分配给 T & F 的数值?
是的,这是预期的 Intel Fortran 的 TRUE 确实是 -1,因为所有位都设置为 1。
此外,您将整数用作逻辑(布尔)变量是完全不规范的。你应该让你的代码长几行并且总是做正确的转换。你的 integer_var = 1*(node(5,L).gt.0)
在 Fortran 中是不允许的,它 将被许多编译器拒绝。如果您删除 1*
gfortran 将发出警告,但您的表单会导致错误。
您可以简单地以符合标准的方式转换您的逻辑值和整数
if (l) then
x = 1
else
x = 0
end if
您可以使用 MERGE()
内部函数或使用 WHERE
.
英特尔 Fortran 的一个简单修复可能是 -fpscomp logicals
英特尔 Fortran,它将 LOGICAL
类型的处理切换为将任何非零值视为 true 并使 .true.
常量等效到整数 1.
仍然要小心,因为它不会使您的程序具有可移植性,它只能解决特定编译器中的一个可移植性问题。
您可以使用 C 互操作逻辑类型来将定义与 Intel C 表示相匹配:
use iso_c_binding
logical(c_bool) :: variable
按照 C99 对 _Bool 的规定,这些将具有 +1 和 0 的值。如果您需要它们与 int
互操作,您必须进行一些简单的转换。 C_int
与 c_bool
不兼容。
根据英特尔编译器的版本,您可能需要使用 -standard-semantics
(或 -fpscomp logicals
)以获得正确的 logical(c_bool)
。我认为这是非常不幸的。
正如其他人所说,对于这种非标准用法,Intel Fortran 的默认设置是设置了低位(奇数)的整数值为真,偶数值(低位清除)为假。常数.TRUE。具有 -1 的位模式。当您进行转换时,它会变得更加复杂,直到版本 17,编译器在这方面还没有完全一致。请注意,如果您使用 -standard-semantics,则隐含 -fpscomp 逻辑。
请阅读 https://software.intel.com/en-us/forums/intel-visual-fortran-compiler-for-windows/topic/275071#comment-1548435 and also the version 17 release notes (https://software.intel.com/en-us/articles/intel-fortran-compiler-170-release-notes) 以了解该版本中数字-逻辑转换处理方式的变化信息。