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



