MERGE_BITS(3) - [BIT:COPY] Merge bits using a mask
result = merge_bits(i, j, mask)
elemental integer(kind=KIND) function merge_bits(i,j,mask)integer(kind=KIND), intent(in) :: i, j, mask
o the result and all input values have the same integer type and KIND with the exception that the mask and either I or J may be a BOZ constant.
A common graphics operation in Ternary Raster Operations is to combine bits from two different sources, generally referred to as bit-blending. MERGE_BITS(3) performs a masked bit-blend of I and J using the bits of the MASK value to determine which of the input values to copy bits from.
Specifically, The k-th bit of the result is equal to the k-th bit of I if the k-th bit of MASK is 1; it is equal to the k-th bit of J otherwise (so all three input values must have the same number of bits).
The resulting value is the same as would result from
ior (iand (i, mask),iand (j, not (mask)))An exception to all values being of the same integer type is that I or J and/or the mask may be a BOZ constant (A BOZ constant means it is either a Binary, Octal, or Hexadecimal literal constant). The BOZ values are converted to the integer type of the non-BOZ value(s) as if called by the intrinsic function INT() with the kind of the non-BOZ value(s), so the BOZ values must be in the range of the type of the result.
o I : value to select bits from when the associated bit in the mask is
1.
o J : value to select bits from when the associated bit in the mask is
0.
o MASK : a value whose bits are used as a mask to select bits from I and J
The bits blended from I and J using the mask MASK.
Sample program:
program demo_merge_bits use,intrinsic :: iso_fortran_env, only : int8, int16, int32, int64 implicit none integer(kind=int16) :: if_one,if_zero,msk character(len=*),parameter :: fmt=(*(g0, 1X))Results:! basic usage print *,MERGE_BITS( 5,10,41) should be 3.=>,merge_bits(5,10,41) print *,MERGE_BITS(13,18,22) should be 4.=>,merge_bits(13,18,22)
! use some values in base2 illustratively: if_one =int(b1010101010101010,kind=int16) if_zero=int(b0101010101010101,kind=int16)
msk=int(b0101010101010101,kind=int16) print ("should get all zero bits =>",b16.16), & & merge_bits(if_one,if_zero,msk)
msk=int(b1010101010101010,kind=int16) print ("should get all ones bits =>",b16.16), & & merge_bits(if_one,if_zero,msk)
! using BOZ values print fmt, & & merge_bits(32767_int16, o12345, 32767_int16), & & merge_bits(o12345, 32767_int16, b0000000000010101), & & merge_bits(32767_int16, o12345, z1234)
! a do-it-yourself equivalent for comparison and validation print fmt, & & ior(iand(32767_int16, 32767_int16), & & iand(o12345, not(32767_int16))), &
& ior(iand(o12345, int(o12345, kind=int16)), & & iand(32767_int16, not(int(o12345, kind=int16)))), &
& ior(iand(32767_int16, z1234), & & iand(o12345, not(int( z1234, kind=int16))))
end program demo_merge_bits
> MERGE_BITS( 5,10,41) should be 3.=> 3 > MERGE_BITS(13,18,22) should be 4.=> 4 > should get all zero bits =>0000000000000000 > should get all ones bits =>1111111111111111 > 32767 32751 5877 > 32767 32767 5877
Fortran 2008
Fortran intrinsic descriptions (license: MIT) @urbanjost
o dshiftl(3) - Combined left shift of the bits of two integers o dshiftr(3) - Combined right shift of the bits of two integers o ibits(3) - Extraction of a subset of bits o merge_bits(3) - Merge bits using a mask o mvbits(3) - Reproduce bit patterns found in one integer in another
Nemo Release 3.1 | merge_bits (3fortran) | November 02, 2024 |