Fortran で、複数個の整数変数の AND や OR を取りたいことがあるのですが、Fortran90 以降で用意された IAND や IOR 関数は引数を二つしか取れず、IAND や IOR を入れ子式に用いなければなりません。
例
m = IOR(I, IOR(J, K))
これを
m = IOR(I, J, K)
の様な形で、かつ任意個の引数を取れるようにするのは Fortran の規格内では出来ません。
しかしながら、Array Constructor を使うと、それに近い形を実現することが出来ます。
考え方は、一次元配列を引数としてその全要素にわたる IAND, IOR をとる関数を用意して、呼び出し側では Array Constructor に、変数を並べることで、配列として関数に引き渡すというものです。つまり
m = IOR( [I, J, K] )
このような形式での呼び出しでよければ、文法の範囲内で目的が実現できます。
ここで、Array Constructor とは Fortran90 で導入されたもので、(/ i, j, k /) が i,j,k を要素に持つ配列とみなされる仕組みです。Fortran2003 で (/..../) の代わりに、[....] と大括弧が使えるようになりました。
下の例では、IAND,IOR 関数にオーバーロードして定義しています。
MODULE m_test IMPLICIT NONE !------------------------ INTERFACE ior MODULE PROCEDURE mor END INTERFACE INTERFACE iand MODULE PROCEDURE mand END INTERFACE !------------------------ CONTAINS !------------------------------------------------------------- INTEGER FUNCTION mand(iarray) INTEGER, INTENT(IN) :: iarray(:) INTEGER :: i mand = -1 ! all bits 1 DO i = 1, SIZE(iarray) mand = IAND(mand, iarray(i)) END DO RETURN END FUNCTION mand !------------------------------------------------------------- INTEGER FUNCTION mor(iarray) INTEGER, INTENT(IN) :: iarray(:) INTEGER :: i mor = 0 ! all bits 0 DO i = 1, SIZE(iarray) mor = IOR(mor, iarray(i)) END DO RETURN END FUNCTION mor !------------------------------------------------------------- END MODULE m_test !================================================================== PROGRAM test USE m_test IMPLICIT NONE INTEGER :: i, j, k, m i = 1 j = 2**2 + 1 k = 2**4 + 1 m = IAND(IAND(i, j), k) PRINT '(B32.32, 1x, B32.32)', m, IAND([i, j, k]) m = IOR(IOR(i, j), k) PRINT '(B32.32, 1x, B32.32)', m, IOR([i, j, k]) STOP END PROGRAM test