- 积分
- 107
- 贡献
-
- 精华
- 在线时间
- 小时
- 注册时间
- 2020-5-20
- 最后登录
- 1970-1-1
|

楼主 |
发表于 2020-6-10 16:47:20
|
显示全部楼层
本帖最后由 往前一步是天涯 于 2020-6-10 16:49 编辑
intmath.f原文件:
module intmath
implicit none
interface ilog2
! log(x)/log(2)
module procedure ilog2_8
module procedure ilog2_4
module procedure ilog2_2
module procedure ilog2_1
end interface ilog2
interface i1log2
! log(x+1)/log(2) unless x=maxint, in which case log(x)/log(2)
module procedure i1log2_8
module procedure i1log2_4
module procedure i1log2_2
module procedure i1log2_1
end interface i1log2
contains
! ----------------------------------------------------------------
function i1log2_8(ival)
implicit none
integer(kind=8), value :: ival
integer(kind=8)::i1log2_8
integer(kind=8), parameter :: one=1
if(ival+one<ival) then
i1log2_8=ilog2_8(ival)
else
i1log2_8=ilog2_8(ival+one)
endif
end function i1log2_8
! ----------------------------------------------------------------
function i1log2_4(ival)
implicit none
integer(kind=4), value :: ival
integer(kind=4)::i1log2_4
integer(kind=4), parameter :: one=1
if(ival+one<ival) then
i1log2_4=ilog2_4(ival)
else
i1log2_4=ilog2_4(ival+one)
endif
end function i1log2_4
! ----------------------------------------------------------------
function i1log2_2(ival)
implicit none
integer(kind=2), value :: ival
integer(kind=2)::i1log2_2
integer(kind=2), parameter :: one=1
if(ival+one<ival) then
i1log2_2=ilog2_2(ival)
else
i1log2_2=ilog2_2(ival+one)
endif
end function i1log2_2
! ----------------------------------------------------------------
function i1log2_1(ival)
implicit none
integer(kind=1), value :: ival
integer(kind=1)::i1log2_1
integer(kind=1), parameter :: one=1
if(ival+one<ival) then
i1log2_1=ilog2_1(ival)
else
i1log2_1=ilog2_1(ival+one)
endif
end function i1log2_1
! ----------------------------------------------------------------
function ilog2_8(i_in)
implicit none
integer(kind=8), value :: i_in
integer(kind=8)::ilog2_8,i
ilog2_8=0
i=i_in
if(i<=0) return
if(iand(i,i-1)/=0) then
!write(0,*) 'iand i-1'
ilog2_8=1
endif
if(iand(i,Z'FFFFFFFF00000000')/=0) then
ilog2_8=ilog2_8+32
i=ishft(i,-32)
!write(0,*) 'iand ffffffff',i,ilog2_8
endif
if(iand(i,Z'00000000FFFF0000')/=0) then
ilog2_8=ilog2_8+16
i=ishft(i,-16)
!write(0,*) 'iand ffff' ,i,ilog2_8
endif
if(iand(i,Z'000000000000FF00')/=0) then
ilog2_8=ilog2_8+8
i=ishft(i,-8)
!write(0,*) 'iand ff',i,ilog2_8
endif
if(iand(i,Z'00000000000000F0')/=0) then
ilog2_8=ilog2_8+4
i=ishft(i,-4)
!write(0,*) 'iand f',i,ilog2_8
endif
if(iand(i,Z'000000000000000C')/=0) then
ilog2_8=ilog2_8+2
i=ishft(i,-2)
!write(0,*) 'iand c',i,ilog2_8
endif
if(iand(i,Z'0000000000000002')/=0) then
ilog2_8=ilog2_8+1
i=ishft(i,-1)
!write(0,*) 'iand 2',i,ilog2_8
endif
end function ilog2_8
! ----------------------------------------------------------------
function ilog2_4(i_in)
implicit none
integer(kind=4), value :: i_in
integer(kind=4)::ilog2_4,i
ilog2_4=0
i=i_in
if(i<=0) return
if(iand(i,i-1)/=0) then
!write(0,*) 'iand i-1'
ilog2_4=1
endif
if(iand(i,Z'FFFF0000')/=0) then
ilog2_4=ilog2_4+16
i=ishft(i,-16)
!write(0,*) 'iand ffff' ,i,ilog2_4
endif
if(iand(i,Z'0000FF00')/=0) then
ilog2_4=ilog2_4+8
i=ishft(i,-8)
!write(0,*) 'iand ff',i,ilog2_4
endif
if(iand(i,Z'000000F0')/=0) then
ilog2_4=ilog2_4+4
i=ishft(i,-4)
!write(0,*) 'iand f',i,ilog2_4
endif
if(iand(i,Z'0000000C')/=0) then
ilog2_4=ilog2_4+2
i=ishft(i,-2)
!write(0,*) 'iand c',i,ilog2_4
endif
if(iand(i,Z'00000002')/=0) then
ilog2_4=ilog2_4+1
i=ishft(i,-1)
!write(0,*) 'iand 2',i,ilog2_4
endif
end function ilog2_4
! ----------------------------------------------------------------
function ilog2_2(i_in)
implicit none
integer(kind=2), value :: i_in
integer(kind=2)::ilog2_2,i
ilog2_2=0
i=i_in
if(i<=0) return
if(iand(i,i-1)/=0) then
!write(0,*) 'iand i-1'
ilog2_2=1
endif
if(iand(i,Z'FF00')/=0) then
ilog2_2=ilog2_2+8
i=ishft(i,-8)
!write(0,*) 'iand ff',i,ilog2_2
endif
if(iand(i,Z'00F0')/=0) then
ilog2_2=ilog2_2+4
i=ishft(i,-4)
!write(0,*) 'iand f',i,ilog2_2
endif
if(iand(i,Z'000C')/=0) then
ilog2_2=ilog2_2+2
i=ishft(i,-2)
!write(0,*) 'iand c',i,ilog2_2
endif
if(iand(i,Z'0002')/=0) then
ilog2_2=ilog2_2+1
i=ishft(i,-1)
!write(0,*) 'iand 2',i,ilog2_2
endif
end function ilog2_2
! ----------------------------------------------------------------
function ilog2_1(i_in)
implicit none
integer(kind=1), value :: i_in
integer(kind=1)::ilog2_1,i
ilog2_1=0
i=i_in
if(i<=0) return
if(iand(i,i-1)/=0) then
!write(0,*) 'iand i-1'
ilog2_1=1
endif
if(iand(i,Z'F0')/=0) then
ilog2_1=ilog2_1+4
i=ishft(i,-4)
!write(0,*) 'iand f',i,ilog2_1
endif
if(iand(i,Z'0C')/=0) then
ilog2_1=ilog2_1+2
i=ishft(i,-2)
!write(0,*) 'iand c',i,ilog2_1
endif
if(iand(i,Z'02')/=0) then
ilog2_1=ilog2_1+1
i=ishft(i,-1)
!write(0,*) 'iand 2',i,ilog2_1
endif
end function ilog2_1
end module intmath
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
c$$$ TEST PROGRAM FOR THIS MODULE
c$$$ program test_intmath
c$$$ use intmath
c$$$ implicit none
c$$$ real(kind=16) :: temp
c$$$ real(kind=16), parameter :: alog2=log(2.0_16)
c$$$ integer(kind=8), parameter :: &
c$$$ & one=1,big=Z'7FFFFFFFFFFFFFFF',small=-2000000_8, &
c$$$ & check=Z'1FFFFFFF'
c$$$ integer(kind=8) :: ival, iret
c$$$ !$OMP PARALLEL DO PRIVATE(ival,temp,iret)
c$$$ do ival=small,big
c$$$ 10 format(Z16,' -- MISMATCH: ',I0,'=>',I0,' (',I0,' = ',F0.10,')')
c$$$ 20 format(Z16,' -- OKAY: ',I0,'=>',I0,' (',I0,' = ',F0.10,')')
c$$$ if(ival+one<ival) then
c$$$ temp=log(real(max(ival,one),kind=16))/alog2
c$$$ else
c$$$ temp=log(real(max(ival+one,one),kind=16))/alog2
c$$$ endif
c$$$ iret=i1log2(ival)
c$$$ if(iret/=ceiling(temp) .or. ival==0 .or. ival==check) then
c$$$ !$OMP CRITICAL
c$$$ if(iret/=ceiling(temp)) then
c$$$ print 10, ival, ival, iret,ceiling(temp),temp
c$$$ else
c$$$ print 20, ival, ival, iret,ceiling(temp),temp
c$$$ endif
c$$$ !$OMP END CRITICAL
c$$$ endif
c$$$ enddo
c$$$ !$OMP END PARALLEL DO
c$$$ end program test_intmath
|
|