回 帖 发 新 帖 刷新版面

主题:[讨论]Fortran 判断奇偶数?

要判断一个整数是奇数还是偶数,用fortran如何编写?

回复列表 (共22个回复)

11 楼

我越发糊涂了,楼主您在 9 楼到底想干什么? 这和你在“楼主”帖子中的原意是否相符?

12 楼

呵呵,确实,新问题最好还是开新贴:)

13 楼

7楼的代码还是复杂
很多编译器支持1作为逻辑真的。
所以if (mod(i,2)) then 就够了,可以减少一次逻辑判断。

但是需要注意的是对语法要求严格的编译器就不行(gfortran)。

以下代码在intel fortran,PGI Fortran上可以正确执行,gfortran编译错误。
program odd_even
integer:: i
read(*,*)i
if (mod(i,2)) then
  write(*,*)i,'is odd.'
else
  write(*,*)i,'is even.'
end if
end program

14 楼

13 楼主:既然你也知道不是所以编译器都支持,那某在 7 楼的语句还是必须的,写出的代码,得尽量符合 Fortran 标准,而不要用“方言”。

再说,您在 13 楼的语句,虽然形式上简单些,但其实编译器会对其进行隐式转换,将整型常量 1 变成逻辑常量 .true., 这个代价未必比 == 小,所以也并不比 7 楼简单。

15 楼

隐式转换是不消耗时间的。
因为逻辑变量本身就是按照整数保存的。
采用这个方法是可以提高效率的,在高性能计算时是有用的。
而且整数变量和逻辑变量隐式转换基本上绝大多数编译器都支持。实际上gfortran说明手册中是支持整数变量和逻辑变量隐式转换的。

 5.11 Implicitly convert `LOGICAL' and `INTEGER' values
 ======================================================
 
 As an extension for backwards compatibility with other compilers, GNU
 Fortran allows the implicit conversion of `LOGICAL' values to `INTEGER'
 values and vice versa.  When converting from a `LOGICAL' to an
 `INTEGER', `.FALSE.' is interpreted as zero, and `.TRUE.' is
 interpreted as one.  When converting from `INTEGER' to `LOGICAL', the
 value zero is interpreted as `.FALSE.' and any nonzero value is
 interpreted as `.TRUE.'.
 
             INTEGER :: i = 1
             IF (i) PRINT *, 'True'
至于编译失败,可能是需要加某个参数把。

16 楼

1。 隐式转换不需要消耗时间,这个可真新奇,有这么好的事情,请出示根据。这个可是一个新时代的“永动机”。阁下提供的文档资料,并未告诉我们其不需要花费时间。

2。 逻辑变量本身按照整数存储,谁告诉你的?反正 Fortran 标准没有规定这些个“内禀”数据类型到底如何表示,Intel Fortran 的帮助文档 Logical Data Representations 明确告诉我们只有最后一对“定义”了,其它的 bit 都是 undefined。整数会 undefined 的吗?

3。 我强调的是程序的可移植性,也就是要尽量符合标准,哪怕付出一点代价,何况这个代价很小。

17 楼

两位别争这个了,实际上在编译器中是会对逻辑表达式中的mod(f,b)及mod(f,b).ne.0做等价处理的。
而无论是从语法严格还是代码的易维护性来说,asymptotic兄都是对的:)

PS:
在debug版本中,mod(f,b)及mod(f,b).ne.0有可能不同;
但在打开了优化的release版本中,两者等效。
(前提,编译器支持隐式转换)

18 楼

本人无意与其进行争论,只是就是论事而已。我在本版 瞎混 了好几个年头,早就看惯了各式各样人和事,随着年龄的增长,对很多东西也无所谓起来。别人愿意听就听,不乐意就算了。但本人恪守一条准则,对不知道的或者把握不准的东西,一般会先翻翻帮助文档,看看 Fortran 标准,尽量不去 误人子弟。

对这个问题,其实 Compiler 的标准化检测会告诉我们:
Fortran 2003 requires a LOGICAL data type in this context.   [MOD]
即使隐式转化发生在 编译 阶段,也是费稍许时间的。

另外,我还看到过用 位运算 来处理这个的,也许会更快;个人觉得在 Fortran 中应该体现不出优势,也许在 C 语言中可以。

19 楼

intel fortran手册里的“永动机”
你看看默认的逻辑变量是怎么定义的。默认逻辑变量长度为4字节,特别最后一句See also default integer.
default logical
The kind for logical constants if no kind type parameter is specified. The default logical kind is affected by the INTEGER directive, the OPTIONS statement, and by compiler options specifying integer size. If none of these are specified, default logical is LOGICAL(4) (LOGICAL*4).   See also default integer.
此外,在Logical Constants里面有这样的描述
Logical data can take on integer data values. Logical data type ranges correspond to their comparable integer data type ranges. For example, the LOGICAL(2) range is the same as the INTEGER(2) range.
当默认kind=4时,整数变量和逻辑变量是对应的。也就是说整数拿来就可以当作逻辑变量。

PS:
1.我和你们不一样,有什么说什么,没把握的也愿意说出来,最起码会有人提醒、批评我,我还能学到东西。如果什么都有百分之百的把握才说,那这个就不是讨论贴了,那叫教育贴。
2.“误人子弟”不敢当,我来这里是讨论的,不是来当老师的,不是来教育别人的,如果看贴的人自己不能鉴别吸收,我只能说他已经是个教育的残品,我不会负责。

20 楼

1。 Fortran 标准明确规定,logical  integer  real 三种数据类型 缺省时, kind 一致,这个没有什么好说的,所有编译器只要其声称符合标准语法就应该满足。
2。 编译器并未规定数据类型具体如何实现,所以,各家编译器完全可以不同,只要符合 Fortran 标准要求就可以了,也可以在这个基础上扩展,不过,这个就是“方言”了。
3。 Fortran 标准明确地说了:IF-Construct 中的条件是 scalar-logical-expression,所以用 整型值的话,严格意义上说是不符合标准的,因此编译器会有如下 Warning: Fortran 2003 requires a LOGICAL data type in this context. 
4。 Intel Fortran 中,关于逻辑常量的表示是:默认 kind = 4,但只是最后一个 bit 有效,其它为都是 undefined 的,这个可以从如下程序看到:

subroutine ABC
  implicit none
  integer:: IA
  logical:: LA

  LA = 1000    
  ! warning #6192: Fortran 2003 does not allow this data type conversion.

  do IA = 0, 100, 1
    if ( IA ) then   
         ! Fortran 2003 requires a LOGICAL data type in this context.
      write(*, *) IA, "is true"
    else
      write(*, *) IA, "is false"
    end if
  end do   ! IA  
  
  return
end subroutine 

Fortran 标准定义的逻辑常量只有两个 .true. .false. ,但若是扩展的话,只要最后一个 bit 对应 0 则是 .false. ,1 则是 .true., 也就是说其它 bit 都是 undefined。
至于楼主 web81 网友在 19 楼提到的
[quote]当默认kind=4时,整数变量和逻辑变量是对应的。也就是说整数拿来就可以当作逻辑变量。
[/quote],我觉得您对帮助文档理解有偏差,这个可以从 Intel Fortran Compiler 给出的警告信息
! warning #6192: Fortran 2003 does not allow this data type conversion
看以看出,两者之所以有一定“关系”,那是编译器的扩展,并非 Fortran 语法所规定。

我不知道,我说清楚了吗?方家可以发表自己的看法。

我来回复

您尚未登录,请登录后再回复。点此登录或注册