关闭警告:扩展:对于gfortran,从(1)转换为逻辑(4)到INTEGER(4)(1)

时间:2015-07-21 20:37:01

标签: boolean fortran gfortran

我故意将一个布尔值数组转换为整数但是我得到了这个警告:

import re
html = """
<td>4.2.2</td>,
<td align="center"><a href="https://blah.org/blah-4.2.2.zip">zip</a> (<a  href="https://blah.org/blah-4.2.2.zip.md5">md5</a> | <a href="https://blah.org/blah-4.2.2.zip.sha1">sha1</a>)</td>,
<td align="center"><a href="https://blah.org/blah-.2.2.tar.gz">tar.gz</a> (<a href="https://blah.org/blah-4.2.2.tar.gz.md5">md5</a>|<ahref="https://blah.org/blah-4.2.2.tar.gz.sha1">sha1</a>)</td>,
<td align="center"><a href="https://blah.org/blah-4.2.2-IIS.zip">IISzip</a> (<a href="https://blah.org/blah-4.2.2-IIS.zip.md5">md5</a> | <a href="https://blah.org/blah-4.2.2-IIS.zip.sha1">sha1</a>)</td>,
<td>4.2.1</td>,
<td align="center"><a href="https://blah.org/blah-4.2.1.zip">zip</a> (<a href="https://blah.org/blah-4.2.1.zip.md5">md5</a> | <a href="https://blah.org/blah-4.2.1.zip.sha1">sha1</a>)</td>,
<td align="center"><a href="https://blah.org/blah-4.2.1.tar.gz">tar.gz</a> (<a href="https://blah.org/blah-4.2.1.tar.gz.md5">md5</a> | <a href="https://blah.org/blah-4.2.1.tar.gz.sha1">sha1</a>)</td>,
<td align="center"><a href="https://blah.org/blah-4.2.1-IIS.zip">IIS zip</a> (<a href="https://blah.org/blah-4.2.1-IIS.zip.md5">md5</a> | <a href="https://blah.org/blah-4.2.1-IIS.zip.sha1">sha1</a>)</td>,
<td>4.2</td>
"""
print re.findall("<td>(\\d+(?:\\.\\d+)*)</td>", html)
我不想要的。我可以

吗?

(1)在Makefile中关闭该警告?

或(更有利)

(2)在代码中明确地进行此转换,以便编译器不用担心?

代码看起来像这样:

Warning: Extension: Conversion from LOGICAL(4) to INTEGER(4) at (1)

其中A = (B.eq.0) A都是大小B整数数组。 (n,1)将填充从B0的整数。我需要稍后再使用这种类型的命令3,我需要A = (B.eq.1)作为整数数组,A当且仅当1B时才是0请求整数,否则应为1。这些应该作为布尔值(.true.0.false.logical,但我将在矩阵运算和汇总中将它们用于转换对于除法的浮点值(必要时),因此gfortran值在这种情况下不是最佳的。

具体来说,我正在寻找这个命令的最快,最矢量化的版本。编写测试元素的包装器很容易,但我希望这是一个提高效率的矢量化操作。

我目前正在使用ifort进行编译,但我希望在intel中使用的任何方法都可用,因为我将与merge编译器进行编译。

更新

wherefloat distance = 10f; void Update() { Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); Shoot(ray.GetPoint(distance)); } public void Shoot(float point) { // shoot from camera location to point here } 都可以完美地用于相关示例。我将研究这些性能指标,并选择最适合矢量化的指标。我也对如何使用矩阵而不仅仅是数组感兴趣,但这不是我原来的问题所以我会发布一个新问题,除非有人想扩展他们的答案,以便如何适应矩阵。

3 个答案:

答案 0 :(得分:2)

我还没有找到要解决的编译器选项(1)。

但是,类型转换非常简单。 The documentation for gfortran指定.true.映射到1false映射到0

请注意,标准未指定转换,其他编译器可能会使用不同的值。具体而言,您不应该依赖于确切的值。

一个简单的merge将为标量和数组提供技巧:

program test
  integer :: int_sca, int_vec(3)
  logical :: log_sca, log_vec(3)

  log_sca = .true.
  log_vec = [ .true., .false., .true. ]

  int_sca = merge( 1, 0, log_sca )
  int_vec = merge( 1, 0, log_vec )

  print *, int_sca
  print *, int_vec
end program

要解决您的更新问题,这与merge

无关
A = merge(1, 0, B == 0)

这可以在任意尺寸的标量和数组上执行。对于后者,这可以很容易地被编译器矢量化。不过,您应该参考编译器的手册。

Casey's answer中的where语句可以以相同的方式扩展。

由于您稍后将它们转换为浮点数,为什么不立即将它们分配为浮点数?假设Areal,则可能如下所示:

A = merge(1., 0., B == 0)

答案 1 :(得分:1)

另一种赞美@AlexanderVogt的方法是使用where构造。

program test
  implicit none
  integer :: int_vec(5)
  logical :: log_vec(5)

  log_vec = [ .true., .true., .false., .true., .false. ]

  where (log_vec)
     int_vec = 1
  elsewhere
     int_vec = 0
  end where

  print *, log_vec
  print *, int_vec
end program test

这会将int_vec的元素分配给true的元素log_vec,其他元素的where元素。

{{1}}构造适用于任何排名数组。

答案 2 :(得分:1)

对于这个特定的例子,你可以一起避免逻辑:

 A=1-(3-B)/3

当然,对于可读性而言并不是那么好,但在性能方面可能还不错。

编辑,运行性能测试,这比where构造快2-3倍,当然绝对符合标准。事实上,你可以抛出绝对值并概括为:

 integer,parameter :: h=huge(1)
 A=1-(h-abs(B))/h

仍然击败了where循环。