虽然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位表示是否本地人等。显然用整数的不同位来表示类似的属性是非常方便的,同时也大大地减少了存储需求。
位运算应用显然不仅仅是这两个方面,上面例子也不见得非常确切,在此只是抛砖引玉罢了。