IBITS 的相反功能?如何使用位子集在 FORTRAN 中存储整数?

Opposite function to IBITS? How to use a subset of bits to store an integer in FORTRAN?

我有一个内存关键的 FORTRAN 程序,它目前使用两个整数数组,第一个使用 4 BYTES 整数,第二个使用 1 BYTE 整数。

两个数组都没有被使用 "fully",即我知道存储在 4 字节数组中的数字不会超过一百万左右(所以我需要超过 2 个字节,但我没有使用4 字节的所有位),同样我只使用 1 字节数组的 2 位作为 "flags"。

为了节省内存,我想尝试将两者结合起来,即使用 4 字节数组最左边的两个位来存储 2 个标志。

现在我知道如果我先设置 INTEGER 值,我可以随后使用 IBSET/IBCLR 设置标志,并且仍然使用 IBITS 函数安全地提取我的整数以提取最右边的 X 位(X=28 in这种情况):

integer(kind=4) :: imark,inum 

imark=600245 ! example number 

! use bits 29 and 30 to store flags...
imark=IBSET(imark,29) 
imark=IBSET(imark,30)

print *,imark ! gives 1611212981

! extract right most bits:
inum=IBITS(imark,0,28)
print *,inum  ! gives back 600245 as desired.

但是,我不知道如何修改整数,同时保留标志的记忆。换句话说,我需要 IBITS 的 opposite 函数,以复制仅分配 X 最右边位的整数。

显然,如果我分配一个新的整数值 (imark=343525),它将重置标志位。我可以编写一个函数,一次循环一个新整数值的最右边的 X 位,然后在我的 4 字节数组中使用 IBSET/IBCLR 设置它们,但这看起来很冗长。但是我没有找到执行此任务的任何内在函数。

Fortran 2008 中有内在函数merge_bits(i, j, mask)。它根据逻辑掩码合并两个整数的位。

您必须准备一个逻辑掩码作为一个整数,它的前两位为 1,其他地方为 0(或相反的一位)。