首页 > 教程 > 正文

阅读排行

Fortran的位运算
2014-10-25 10:56:23   来源:jason388@Fcode研讨团队   评论:0 点击:

本文简单介绍了Fortran的位运算及应用,并附有代码实例讲解。位运算在某些情况下,比如不同格式二进制文件的读写、较多量的逻辑型变量存储应用,都非常高效和有力。

位运算是针对整数在计算机中的二进制表示的每个位(bit)进行操作的运算。Fortran95标准首次在Fortran语言中引进了位运算支持,Fortran2008标准对位运算功能又进行了增强。与C采用位运算符不同,Fortran是通过内置函数实现位运算功能的。Fortran95增加了10个位运算函数和1个位运算子程序,通过这些内置过程基本上实现了C位运算符能够实现的所有功能。Fortran2008增加了4个位比较函数、2个联合移位函数、4个位计数函数、2个位设置函数、3个移位函数、1个位合并函数和3个位变换函数。除了移位函数和Fortran95的移位函数有重叠外,其他Fortran2008新增的位函数都是对位运算功能的进一步增强。

虽然Fortran95即已经支持位运算,但大部分Fortran书籍对位运算的介绍要么一笔带过要么只字不提。位运算真的无用或不值得Fortran程序员关注吗?答案显然是No。简单来讲,位运算应用主要有两个方面,一个是某些特殊算法的实现,另一个是利用位操作来实现二选一的属性设置。下面通过几个简单例子对此加以介绍。
module bit_computation
   use iso_fortran_env, only : int64
   implicit none

 contains
   ! add two integers by bit operations
   function add(a,b) result(c)
     integer(int64),value :: a,b
     integer(int64) :: c
     do while(a/=0)
        c=iand(b,a)
        b=ieor(b,a)
        a=shiftl(c,1)
     end do
     c=b
   end function add

   ! multiply two integers by bit operations
   function multiply(a,b) result(c)
     integer(int64),value :: a,b
     integer(int64) :: c
     c=0
     do while(a/=0)
        if(iand(a,1)/=0)then
           c=c+b
        end if
        a=shiftr(a,1)
        b=shiftl(b,1)
     end do
   end function multiply

   ! check if a is power of 2
   function ispower_of_two(a) result(b)
     integer(int64),value :: a
     logical :: b
     !if(iand(a,a-1)==0 .and. a/=0)then
     if(iand(a,-a)==a .and. a/=0)then
        b=.true.
     else
        b=.false.
     end if
   end function ispower_of_two

   function iseven(a) result(b)
     integer(int64),value :: a
     logical :: b
     if(iand(a,1)==0)then
        b=.true.
     else
        b=.false.
     end if
   end function iseven
   subroutine swap(a,b)
     integer(int64) :: a,b
     a=ieor(a,b)
     b=ieor(a,b)
     a=ieor(a,b)
   end subroutine swap

 end module bit_computation

program www_fcode_cn
 use iso_fortran_env, only : int64
 use bit_computation
 implicit none
 integer(int64) :: a,b
 print*,'a,b='
 read*,a,b
 print*,'a*b=',multiply(a,b)
 print*,'a+b=',add(a,b)
 print*,'is a power of 2:',ispower_of_two(a)
 print*,'is a an even? ',iseven(a)
 call swap(a,b)
 print*,'after swap a and b= ',a,b
end program www_fcode_cn
上面代码中的ispower_of_two函数用其它方法实现是非常麻烦的,通过这个例子可以看出位运算的威力。

下面代码为属性设置的例子。
program www_fcode_cn
  implicit none
  integer(1) :: flag
  enum,bind(c)
    enumerator :: male=0, english, age, pay, local
  end enum
  flag=0
  flag=ibset(flag,male)
  flag=ibset(flag,age)
  flag=ibset(flag,pay)
  if(btest(flag,male))print '(a)','This is a man.'
end program www_fcode_cn

其中通过整数flag从低到高的5个bit表示一个人的几个不同属性,比如第0位表示是否男人,第1位表示是否会英语,第2位表示是否年龄大于30岁,第4位表示工资是否超过某个数,第5位表示是否本地人等。显然用整数的不同位来表示类似的属性是非常方便的,同时也大大地减少了存储需求。
位运算应用显然不仅仅是这两个方面,上面例子也不见得非常确切,在此只是抛砖引玉罢了。

相关热词搜索:位运算

上一篇:配置VS使用winteracter
下一篇:Fortran流文件-读写二进制任意位置

分享到: 收藏