stdlib_bitsets
模块stdlib_bitsets
模块实现了位集类型。位集是 bits
个二进制值的序列的紧凑表示。它也可以等效地被视为逻辑值的序列或整数 0 ... bits-1
的子集。例如,值 1110
可以被认为定义了整数 [1, 2, 3] 的子集。位从 0 到 bits(bitset)-1
索引。当空间节省在需要大量紧密相关的逻辑值的应用程序中至关重要时,使用位集。它还可以通过减少内存流量来提高性能。为了实现位集,该模块定义了三种位集类型、多个常量、可以读入和读出字符串和格式化文件的字符字符串字面量、可以读入和读出字符串的简单字符字符串字面量、赋值、过程、方法和运算符。请注意,该模块假设使用二进制补码整数,但所有当前的 Fortran 95 及更高版本的处理器都使用此类整数。
请注意,该模块定义了许多“二元”过程,这些过程有两个位集参数。这些参数必须是相同类型,并且应该具有相同数量的 bits
。出于性能考虑,该模块不会强制执行 bits
约束,但违反该约束会导致未定义的行为。这种未定义的行为包括对那些超出较小位集中定义的 bits
数量的位的未定义值。未定义的行为还可能包括尝试在较小位集中寻址超出定义的 bits
数量的位的“分段错误”。其他问题也可能发生。
该模块定义了几个公共整数常量,几乎所有这些常量都旨在充当错误代码,用于通过可选的 stat
参数报告问题。一个常量,bits_kind
,是用于索引位和报告位计数的整数种类值。其他作为错误代码的常量总结如下
错误代码 | 摘要 |
---|---|
success |
没有发现问题 |
alloc_fault |
内存分配失败 |
array_size_invalid_error |
尝试在 bitset_64 中定义负位或超过 64 位 |
char_string_invalid_error |
在字符字符串中发现无效字符 |
char_string_too_large_error |
字符字符串太大,无法编码在位集中 |
char_string_too_small_error |
字符字符串太小,无法保存预期的位数 |
index_invalid_error |
位字符串的索引小于零或大于位的数量 |
integer_overflow_error |
尝试定义大于 huge(0_bits_kind) 的整数值 |
read_failure |
read 语句失败 |
eof_failure |
read 语句中出现意外的“文件末尾” |
write_failure |
write 语句失败 |
stdlib_bitsets
派生类型stdlib_bitsets
模块定义了三种派生类型,bitset_type
、bitset_64
和 bitset_large
。bitset_type
是一个抽象类型,作为 bitset_64
和 bitset_large
的祖先。bitset_type
定义了一个方法,bits
,并且它所有其他方法都推迟到其扩展。bitset_64
是一个可以处理多达 64 位的位集。bitset_large
是一个可以处理多达 huge(0_bits_kind)
位的位集。位集类型的所有属性都是私有的。各种类型都定义了一系列二进制值:0 或 1。在某些情况下,为序列的每个元素关联一个逻辑值 test
很有用,其中 test
为 .true.
如果值为 1,否则为 .false.
。该类型实体中此类值的个数被称为 bits
。位按位置顺序排列,该位置从 0 到 bits-1
索引。bitset_type
仅用作 class
来定义可以是 bitset_64
或 bitset_large
的实体。使用这些类型的语法是
class(
bitset_type ) :: variable
type(
bitset_64 ) :: variable
和
type(
bitset_large ) :: variable
位集值可以表示为源代码中的 bitset-literal-constant 字符串,或者表示为格式化文件和非常量字符串中的 bitset-literal。
bitset-literal-constant 是 ' bitset-literal ' 或 " bitset-literal "
bitset-literal 是 bitsize-literal binary-literal
bitsize-literal 是 S digit [ digit ] ...
binary-literal 是 B binary-digit [ binary-digit ] ...
digit 是 0 或 1 或 2 或 3 或 4 或 5 或 6 或 7 或 8 或 9
binary-digit 是 0 或 1
bitset-literal 由两部分组成:bitsize-literal 和 binary-literal。bitsize-literal 中的十进制数字序列被解释为 bits
的十进制值。binary-literal 值被解释为一系列位值,并且字面量中必须有与 bits
相同数量的二进制数字。二进制数字序列被视为无符号整数,其中第 i 个数字对应于 bits-i
位位置。
在定义 bitset-literal 时,我们还定义了 binary-literal。虽然不适合文件 I/O,但 binary-literal 适合从字符字符串中传输到字符字符串。在这种情况下,字符串的长度是位的数量,并且字符串中的所有字符都必须是“0”或“1”。
stdlib_bitsets
模块定义了许多操作
bitset_type
的“一元”方法,bitset_64
或 bitset_large
的“二元”过程重载,bitset_64
或 bitset_large
的“二元”比较运算符。每个类别将分别讨论。
bitset_type
方法表bitset_type
类有许多方法。除了 bits
之外,所有方法都是推迟的。这些方法包括所有具有一个 bitset_type
类参数的过程。具有两个 bitset_64
或 bitset_large
类型参数的过程不是方法,在单独的过程表中进行总结。这些方法总结如下
方法名称 | 类 | 摘要 |
---|---|---|
all |
函数 | 如果所有位都是 1,则为 .true. ,否则为 .false. |
any |
函数 | 如果任何位都是 1,则为 .true. ,否则为 .false. |
bit_count |
函数 | 返回值为 1 的位的数量 |
bits |
函数 | 返回位集中位的数量 |
clear |
子程序 | 将一个或多个位的序列设置为 0 |
flip |
子程序 | 翻转一个或多个位的序列的值 |
from_string |
子程序 | 从字符串中读取位集,将其视为二进制字面量 |
init |
子程序 | 创建一个大小为 bits 的新位集,其中没有位设置 |
input |
子程序 | 从非格式化 I/O 单位读取一个位集 |
none |
函数 | 如果没有任何位为 1,则为 .true. ,否则为 .false. |
not |
子程序 | 对所有位执行逻辑 not 运算 |
output |
子程序 | 将位集写入非格式化 I/O 单位 |
read_bitset |
子程序 | 从字符型字符串或格式化 I/O 单位中的位集文字读取位集。 |
设置 |
子程序 | 将一个或多个位的序列设置为 1。 |
测试 |
函数 | 如果位置 pos 处的位为 1,则为 .true. ,否则为 .false. 。 |
转换为字符串 |
子程序 | 将位集表示为二进制文字。 |
值 |
函数 | 如果位置 pos 处的位为 1,则为 1,否则为 0。 |
写入位集 |
子程序 | 将位集作为位集文字写入字符型字符串或格式化 I/O 单位。 |
具有两个 bitset_large
或 bitset_64
类型的参数的过程必须具有相同已知类型的两个参数,这将阻止它们成为方法。位运算 "逻辑" 过程(and
、and_not
、or
和 xor
)也要求两个位集参数具有相同数量的位,否则结果将是未定义的。这些过程在以下表格中总结。
过程名称 | 类 | 摘要 |
---|---|---|
和 |
元素子例程 | 将 self 设置为 self 和 set2 中原始位按位 and 的结果。 |
and_not |
元素子例程 | 将 self 设置为 self 中原始位与 set2 的否定按位 and 的结果。 |
提取 |
子程序 | 从 old 中的范围内创建一个新的位集 new 。 |
或 |
元素子例程 | 将 self 设置为 self 和 set2 中原始位按位 or 的结果。 |
异或 |
元素子例程 | 将 self 设置为 self 和 set2 中原始位按位异或 or 的结果。 |
该模块使用内在赋值运算符 =
来创建原始位集的副本。它还定义了对类型为 int8
、int16
、int32
和 int64
的逻辑类型的秩为一的数组的赋值。在对逻辑数组的赋值中,数组索引 i
映射到位位置 pos=i-1
,.true.
映射到已设置的位,.false.
映射到未设置的位。
program example_assignment
use stdlib_bitsets
use stdlib_kinds, only: int8, int32
implicit none
logical(int8) :: logical1(64) = .true.
logical(int32), allocatable :: logical2(:)
type(bitset_64) :: set0, set1
set0 = logical1
if (set0%bits() /= 64) then
error stop &
' initialization with logical(int8) failed to set'// &
' the right size.'
else if (.not. set0%all()) then
error stop ' initialization with'// &
' logical(int8) failed to set the right values.'
else
write (*, *) 'Initialization with logical(int8) succeeded.'
end if
set1 = set0
if (set1 == set0) &
write (*, *) 'Initialization by assignment succeeded'
logical2 = set1
if (all(logical2)) then
write (*, *) 'Initialization of logical(int32) succeeded.'
end if
end program example_assignment
具有两个 bitset_large
或 bitset_64
类型的参数的比较运算符必须具有相同已知类型的两个参数,这将阻止它们成为方法。操作数还必须具有相同数量的位,否则结果将是未定义的。这些运算符在以下表格中总结。
运算符 | 描述 |
---|---|
== , .eq. |
如果 set1 和 set2 中的所有位具有相同的值,则为 .true. ,否则为 .false. 。 |
/= , .ne. |
如果 set1 和 set2 中的任何位在值上不同,则为 .true. ,否则为 .false. 。 |
> , .gt. |
如果 set1 和 set2 中的位在值上不同,并且最高阶不同的位在 set1 中为 1,在 set2 中为 0,则为 .true. ,否则为 .false. 。 |
>= , .ge. |
如果 set1 和 set2 中的位相同,或者最高阶不同的位在 set1 中为 1,在 set2 中为 0,则为 .true. ,否则为 .false. 。 |
< , .lt. |
如果 set1 和 set2 中的位在值上不同,并且最高阶不同的位在 set1 中为 0,在 set2 中为 1,则为 .true. ,否则为 .false. 。 |
<= , .le. |
如果 set1 和 set2 中的位相同,或者最高阶不同的位在 set1 中为 0,在 set2 中为 1,则为 .true. ,否则为 .false. 。 |
stdlib_bitsets
方法和过程的规范all
- 确定 self
中的所有位是否已设置。实验性
确定 self
中的所有位是否都设置为 1。
result = self %
all ()
元素函数。
self
: 应为类 bitset_type
的标量表达式。它是一个 intent(in)
参数。
结果是默认逻辑标量。如果 self
中的所有位都已设置,则结果为 .true.
,否则为 .false.
。
program example_all
use stdlib_bitsets
implicit none
character(*), parameter :: &
bits_all = '111111111111111111111111111111111'
type(bitset_64) :: set0
call set0%from_string(bits_all)
if (.not. set0%all()) then
error stop "FROM_STRING failed to interpret"// &
"BITS_ALL's value properly."
else
write (*, *) "FROM_STRING transferred BITS_ALL properly"// &
" into set0."
end if
end program example_all
and
- 两个位集的位按位 and
。实验性
将 set1
中的位设置为 set1
和 set2
中原始位按位 and
的结果。请注意,set1
和 set2
必须具有相同数量的位,否则结果将是未定义的。
call
and (set1, set2)
元素子例程。
set1
: 应为 bitset_64
或 bitset_large
标量变量。它是一个 intent(inout)
参数。返回时,set1
中位的 value 将是 set1
中原始位与 set2
中相应位按位 and
的结果。
set2
: 应为与 set1
类型相同的标量表达式。它是一个 intent(in)
参数。请注意,set2
还必须与 set1
具有相同数量的位。
program example_and
use stdlib_bitsets
implicit none
type(bitset_large) :: set0, set1
call set0%init(166)
call set1%init(166)
call and(set0, set1) ! none none
if (set0%none()) write (*, *) 'First test of AND worked.'
call set0%not()
call and(set0, set1) ! all none
if (set0%none()) write (*, *) 'Second test of AND worked.'
call set1%not()
call and(set0, set1) ! none all
if (set0%none()) write (*, *) 'Third test of AND worked.'
call set0%not()
call and(set0, set1) ! all all
if (set0%all()) write (*, *) 'Fourth test of AND worked.'
end program example_and
and_not
- 一个位集与另一个位集的否定按位 and
。实验性
将 set1
的位设置为 set1
的位与 set2
中相应位的按位否定按位 and
的结果。请注意,set1
和 set2
必须具有相同数量的位,否则结果将是未定义的。
call
and_not (set1, set2)
元素子例程。
set1
: 应为标量 bitset_64
或 bitset_large
变量。它是一个 intent(inout)
参数。返回时,set1
中位的 value 将是 set1
中原始位与 set2
中相应位否定按位 and
的结果。
set2
: 应为与 set1
类型相同的标量表达式。它是一个 intent(in)
参数。请注意,它还应与 set1
具有相同数量的位,否则结果将是未定义的。
program example_and_not
use stdlib_bitsets
implicit none
type(bitset_large) :: set0, set1
call set0%init(166)
call set1%init(166)
call and_not(set0, set1) ! none none
if (set0%none()) write (*, *) 'First test of AND_NOT worked.'
call set0%not()
call and_not(set0, set1) ! all none
if (set0%all()) write (*, *) 'Second test of AND_NOT worked.'
call set0%not()
call set1%not()
call and_not(set0, set1) ! none all
if (set0%none()) write (*, *) 'Third test of AND_NOT worked.'
call set0%not()
call and_not(set0, set1) ! all all
if (set0%none()) write (*, *) 'Fourth test of AND_NOT worked.'
end program example_and_not
any
- 确定是否设置了任何位。实验性
确定 self
中是否设置了任何位。
result = self %
any ()
元素函数。
self
: 应为类 bitset_type
的标量表达式。它是一个 intent(in)
参数。
结果是默认逻辑标量。如果 self
中的任何位都已设置,则结果为 .true.
,否则为 .false.
。
program example_any
use stdlib_bitsets
implicit none
character(*), parameter :: &
bits_0 = '0000000000000000000'
type(bitset_64) :: set0
call set0%from_string(bits_0)
if (.not. set0%any()) then
write (*, *) "FROM_STRING interpreted "// &
"BITS_0's value properly."
end if
call set0%set(5)
if (set0%any()) then
write (*, *) "ANY interpreted SET0's value properly."
end if
end program example_any
bit_count
- 返回已设置的位数。实验性
返回 self
中设置为 1 的位数。
result = self %
bit_count ()
元素函数。
self
: 应为类 bitset_type
的标量表达式。它是一个 intent(in)
参数。
结果是 kind 为 bits_kind
的整数标量,等于 self
中已设置的位数。
program example_bit_count
use stdlib_bitsets
implicit none
character(*), parameter :: &
bits_0 = '0000000000000000000'
type(bitset_64) :: set0
type(bitset_large) :: set1
logical, allocatable :: logi(:)
call set0%from_string(bits_0)
if (set0%bit_count() == 0) then
write (*, *) "FROM_STRING interpreted "// &
"BITS_0's value properly."
end if
call set0%set(5)
if (set0%bit_count() == 1) then
write (*, *) "BIT_COUNT interpreted SET0's value properly."
end if
allocate( logi(1000), source=.false.)
logi(1::7) = .true.
set1 = logi
if (set1%bit_count() == count(logi)) then
write (*, *) "BIT_COUNT interpreted SET1's value properly."
end if
end program example_bit_count
bits
- 返回位数。实验性
报告 self
中的位数。
result = self %
bits ()
元素函数。
self
: 应为类 bitset_type
的标量表达式。它是一个 intent(in)
参数。
结果是 kind 为 bits_kind
的整数标量,等于 self
中定义的位数。
program example_bits
use stdlib_bitsets
implicit none
character(*), parameter :: &
bits_0 = '0000000000000000000'
type(bitset_64) :: set0
call set0%from_string(bits_0)
if (set0%bits() == 19) then
write (*, *) "FROM_STRING interpreted "// &
"BITS_0's size properly."
end if
end program example_bits
clear
- 清除一个或多个位的序列。实验性
如果只存在 pos
,则清除 self
中位置为 pos
的位。
如果 start_pos
和 end_pos
存在且 end_pos >= start_pos
,则清除 self
中位置从 start_pos
到 end_pos
的位。
如果 start_pos
和 end_pos
存在且 end_pos < start_pos
,则 self
保持不变。
注意:超出 0 到 bits(set) -1
范围的位置将被忽略。
call self %
clear (pos)
或
call self %
clear (start_pos, end_pos)
元素子例程
self
: 应为类 bitset_type
的标量变量。它是一个 intent(inout)
参数。
pos
: 应为 kind 为 bits_kind
的整数标量表达式。它是一个 intent(in)
参数。
start_pos
: 应为 kind 为 bits_kind
的整数标量表达式。它是一个 intent(in)
参数。
end_pos
: 应为 kind 为 bits_kind
的整数标量表达式。它是一个 intent(in)
参数。
program example_clear
use stdlib_bitsets
implicit none
type(bitset_large) :: set0
call set0%init(166)
call set0%not()
if (set0%all()) write (*, *) 'SET0 is properly initialized.'
call set0%clear(165)
if (.not. set0%test(165)) write (*, *) 'Bit 165 is cleared.'
call set0%clear(0, 164)
if (set0%none()) write (*, *) 'All bits are cleared.'
end program example_clear
extract
- 从旧位集中的范围内创建一个新的位集。实验性
从位集 old
中的范围 start_pos
到 stop_pos
创建一个新的位集 new
。如果 start_pos
大于 stop_pos
,则新的位集为空。如果 start_pos
小于零或 stop_pos
大于 bits(old)-1
,则如果 status
存在,则其值为 index_invalid_error
,否则处理将以信息性消息停止。
call
extract (new, old, start_pos, stop_pos, status )
子例程
new
: 应为标量 bitset_64
或 bitset_large
变量。它是一个 intent(out)
参数。它将是新的位集。
old
: 应为与 new
类型相同的标量表达式。它是一个 intent(in)
参数。它将是源位集。
start_pos
: 应为 kind 为 bits_kind
的整数标量表达式。它是一个 intent(in)
参数。
stop_pos
: 应为 kind 为 bits_kind
的整数标量表达式。它是一个 intent(in)
参数。
status
(可选):应为标量默认整数变量。它是一个 intent(out)
参数。如果存在,它应具有以下值之一
success
- 未发现问题
index_invalid_error
- start_pos
小于零或 stop_pos
大于 bits(old)-1
。
program example_extract
use stdlib_bitsets
implicit none
type(bitset_large) :: set0, set1
call set0%init(166)
call set0%set(100, 150)
call extract(set1, set0, 100, 150)
if (set1%bits() == 51) &
write (*, *) 'SET1 has the proper size.'
if (set1%all()) write (*, *) 'SET1 has the proper values.'
end program example_extract
flip
- 反转一个或多个位的 value。实验性
反转一个或多个位的 value。
pos
,则反转 self
中位置为 pos
的位的 value。* 如果 start_pos
和 end_pos
存在且 end_pos >= start_pos
,则反转 self
中位置从 start_pos
到 end_pos
的位的 value。
end_pos < start_pos
,则 self
保持不变。call self %
flip (pos)
或
call self %
flip (start_pos, end_pos)
元素子例程。
self
: 应为类 bitset_type
的标量变量。它是一个 intent(inout)
参数。
pos
: 应为 kind 为 bits_kind
的整数标量表达式。它是一个 intent(in)
参数。
start_pos
: 应为 kind 为 bits_kind
的整数标量表达式。它是一个 intent(in)
参数。
end_pos
: 应为 kind 为 bits_kind
的整数标量表达式。它是一个 intent(in)
参数。
program example_flip
use stdlib_bitsets
implicit none
type(bitset_large) :: set0
call set0%init(166)
if (set0%none()) write (*, *) 'SET0 is properly initialized.'
call set0%flip(165)
if (set0%test(165)) write (*, *) 'Bit 165 is flipped.'
call set0%flip(0, 164)
if (set0%all()) write (*, *) 'All bits are flipped.'
end program example_flip
from_string
- 从二进制文字初始化位集。实验性
从 string
初始化位集 self
,将 string
视为二进制文字。
call self %
from_string (string[, status])
子例程
self
: 应为类 bitset_type
的标量变量。它是一个 intent(out)
参数。
string
: 应为标量默认字符表达式。它是一个 intent(in)
参数。它应仅包含字符 "0" 和 "1"。
status
(可选): 应为一个标量默认整型变量。它是一个 intent(out)
参数。如果存在,则在返回时其值应为本模块中定义的错误代码之一。如果不存在,并且其值不应为 success
,则处理将停止,其停止代码为信息性文本。它应具有以下错误代码之一
success
- 如果没有发现问题,
alloc_fault
- 如果位集的分配失败
char_string_too_large_error
- 如果 string
太大,或
char_string_invalid_error
- 如果字符串包含无效字符。
program example_from_string
use stdlib_bitsets
implicit none
character(*), parameter :: &
bits_all = '111111111111111111111111111111111'
type(bitset_64) :: set0
call set0%from_string(bits_all)
if (bits(set0) /= 33) then
error stop "FROM_STRING failed to interpret "// &
"BITS_ALL's size properly."
else if (.not. set0%all()) then
error stop "FROM_STRING failed to interpret"// &
"BITS_ALL's value properly."
else
write (*, *) "FROM_STRING transferred BITS_ALL properly"// &
" into set0."
end if
end program example_from_string
init
- bitset_type
初始化例程实验性
bitset_type
初始化例程。
call self %
init (bits [, status])
子程序。
self
: 应为一个标量 bitset_64
或 bitset_large
变量。它是一个 intent(out)
参数。
bits
: 应为一个标量整型表达式,其种类为 bits_kind
。它是一个 intent(in)
参数,如果存在,则指定 set
中的位数。负值,或如果 self
的类型为 bitset_64
,则大于 64 的值是一个错误。
status
(可选): 应为一个标量默认整型变量。它是一个 intent(out)
参数,如果存在,则返回一个错误代码,指示在处理 init
时发现的任何问题,如果不存在,并且发现了错误,则会导致处理停止,并使用信息性停止代码。它可以具有以下任何错误代码
success
- 未发现问题
alloc_fault
- self
的类型为 bitset_large
并且内存分配失败
array_size_invalid_error
- bits
存在且具有负值,或者当 self
的类型为 bitset_64
时,其值大于 64。
program example_init
use stdlib_bitsets
implicit none
type(bitset_large) :: set0
call set0%init(166)
if (set0%bits() == 166) &
write (*, *) 'SET0 has the proper size.'
if (set0%none()) write (*, *) 'SET0 is properly initialized.'
end program example_init
input
- 从无格式文件读取位集实验性
从无格式文件中的二进制表示形式读取位集。
call self %
input (unit [, status])
子例程
self
: 应为一个标量变量,其类为 bitset_64
或 bitset_large
。它是一个 intent(out)
参数。
unit
: 应为一个标量默认整型表达式。它是一个 intent(in)
参数。其值必须是打开的无格式文件的逻辑单元号,该文件具有 read
或 readwrite
访问权限,并定位在由同一处理器通过 bitset_type
output
子例程写入的位集值的开头。
status
(可选): 应为一个标量默认整型变量。如果存在,则其值应为本模块中定义的错误代码之一。如果不存在,并且其值不应为 success
,则处理将停止,并使用信息性停止代码。此 status
的允许错误代码值为
success
- 未发现问题
alloc_fault
- self
的类型为 bitset_large
并且内存分配失败。
array_size_invalid_error
- 如果从 unit
读取的位数为负数或大于 64,并且 self
的类为 bitset_64
。
read_failure
- 读取语句失败
program example_input
use stdlib_bitsets
implicit none
character(*), parameter :: &
bits_0 = '000000000000000000000000000000000', &
bits_1 = '000000000000000000000000000000001', &
bits_33 = '100000000000000000000000000000000'
integer :: unit
type(bitset_64) :: set0, set1, set2, set3, set4, set5
call set0%from_string(bits_0)
call set1%from_string(bits_1)
call set2%from_string(bits_33)
open (newunit=unit, file='test.bin', status='replace', &
form='unformatted', action='write')
call set2%output(unit)
call set1%output(unit)
call set0%output(unit)
close (unit)
open (newunit=unit, file='test.bin', status='old', &
form='unformatted', action='read')
call set5%input(unit)
call set4%input(unit)
call set3%input(unit)
close (unit)
if (set3 /= set0 .or. set4 /= set1 .or. set5 /= set2) then
error stop 'Transfer to and from units using '// &
' output and input failed.'
else
write (*, *) 'Transfer to and from units using '// &
'output and input succeeded.'
end if
end program example_input
none
- 确定是否没有设置位实验性
确定 self
中是否没有设置位。
result = self %
none ()
元素函数。
self
: 应为类 bitset_type
的标量表达式。它是一个 intent(in)
参数。
结果是一个默认逻辑标量。如果 self
中没有设置位,则结果为 .true.
,否则结果为 .false.
。
program example_none
use stdlib_bitsets
implicit none
character(*), parameter :: &
bits_0 = '0000000000000000000'
type(bitset_large) :: set0
call set0%from_string(bits_0)
if (set0%none()) then
write (*, *) "FROM_STRING interpreted "// &
"BITS_0's value properly."
end if
call set0%set(5)
if (.not. set0%none()) then
write (*, *) "NONE interpreted SET0's value properly."
end if
end program example_none
not
- 对位集执行逻辑补运算实验性
对 self
的位执行逻辑补运算。
call self %
not ()
元素子例程。
self
应为一个标量变量,其类为 bitset_type
。它是一个 intent(inout)
参数。在返回时,其位应为其输入值的逻辑补运算。
program example_not
use stdlib_bitsets
implicit none
type(bitset_large) :: set0
call set0%init(155)
if (set0%none()) then
write (*, *) "FROM_STRING interpreted "// &
"BITS_0's value properly."
end if
call set0%not()
if (set0%all()) then
write (*, *) "ALL interpreted SET0's value properly."
end if
end program example_not
or
- 两个位集的位的按位或运算实验性
用 set1
的位与 set2
的位的按位 or
运算结果替换 set1
的原始位。请注意,set1
和 set2
必须具有相同的位数,否则结果将是未定义的。
call
or (set1, set2)
元素子例程。
set1
: 应为一个标量 bitset_64
或 bitset_large
变量。它是一个 intent(inout)
参数。在返回时,setf
中位的数值为 set1
中原始位与 set2
中对应位的按位 or
运算结果。
set2
: 应为与 set1
类型相同的标量表达式。它是一个 intent(in)
参数。请注意,bits(set2)
必须等于 bits(set1)
,否则结果将是未定义的。
program example_or
use stdlib_bitsets
implicit none
type(bitset_large) :: set0, set1
call set0%init(166)
call set1%init(166)
call or(set0, set1) ! none none
if (set0%none()) write (*, *) 'First test of OR worked.'
call set0%not()
call or(set0, set1) ! all none
if (set0%all()) write (*, *) 'Second test of OR worked.'
call set0%not()
call set1%not()
call or(set0, set1) ! none all
if (set0%all()) write (*, *) 'Third test of OR worked.'
call set0%not()
call or(set0, set1) ! all all
if (set0%all()) write (*, *) 'Fourth test of OR worked.'
end program example_or
output
- 将位集的二进制表示形式写入文件实验性
将位集的二进制表示形式写入无格式文件。
call self %
output (unit[, status])
子程序。
self
: 应为一个标量表达式,其类为 bitset_64
或 bitset_large
。它是一个 intent(in)
参数。
unit
: 应为一个标量默认整型表达式。它是一个 intent(in)
参数。其值必须是打开的无格式文件的 I/O 单元号,该文件具有 write
或 readwrite
访问权限。
status
(可选): 应为一个标量默认整型变量。它是一个 intent(out)
参数。如果存在,则在返回时,其将具有 success
或 write_failure
的值。如果不存在,并且其不应具有 success
的值,则处理将停止,并使用信息性停止代码。这两个代码值具有以下含义
success
- 未发现问题
write_failure
- 写入语句发生故障。
program example_output
use stdlib_bitsets
implicit none
character(*), parameter :: &
bits_0 = '000000000000000000000000000000000', &
bits_1 = '000000000000000000000000000000001', &
bits_33 = '100000000000000000000000000000000'
integer :: unit
type(bitset_64) :: set0, set1, set2, set3, set4, set5
call set0%from_string(bits_0)
call set1%from_string(bits_1)
call set2%from_string(bits_33)
open (newunit=unit, file='test.bin', status='replace', &
form='unformatted', action='write')
call set2%output(unit)
call set1%output(unit)
call set0%output(unit)
close (unit)
open (newunit=unit, file='test.bin', status='old', &
form='unformatted', action='read')
call set5%input(unit)
call set4%input(unit)
call set3%input(unit)
close (unit)
if (set3 /= set0 .or. set4 /= set1 .or. set5 /= set2) then
error stop 'Transfer to and from units using '// &
' output and input failed.'
else
write (*, *) 'Transfer to and from units using '// &
'output and input succeeded.'
end if
end program example_output
read_bitset
- 使用 bitset_literal 的值初始化 self
实验性
读取 bitset-literal 并使用相应的值初始化 self
。
call self %
read_bitset (string[, status])
或
call self %
read_bitset (unit[, advance, status])
子例程
self
: 应为一个标量变量,其类为 bitset_type
。它是一个 intent(out)
参数。在成功返回后,它将使用 bitset-literal 的值进行初始化。
string
(可选): 应为一个标量默认字符表达式。它是一个 intent(in)
参数。它将包含一个左对齐的 bitset-literal,以字符串的结尾或空格终止。
unit
(可选): 应为一个标量默认整型表达式。它是一个 intent(in)
参数。其值必须是打开的格式化文件的 I/O 单元号,该文件具有 read
或 readwrite
访问权限,并定位在 bitset-literal 的开头。
advance
(可选): 应为一个标量默认字符表达式。它是一个 intent(in)
参数。它是 unit
的最终读取的 advance
说明符。如果存在,则其应具有 'yes'
或 'no'
的值。如果不存在,则其默认值为 'yes'
。
status
(可选): 应为一个标量默认整型变量。它是一个 intent(out)
参数。如果存在,则在返回时,其应具有本模块的错误代码之一的值。如果不存在,并且其不应具有 success
的值,则处理将停止,并使用消息作为其错误代码。可能的错误代码为
success
- 未发现问题;
alloc_fault
- 如果 self
的类为 bitset_large
并且位的分配失败;
array_size_invalid_error
- 如果 bitset-literal 的位值大于 64 并且 self
的类为 bitset_64
;
char_string_invalid_error
- 如果 bitset-literal
包含无效字符;
char_string_too_small_error
- 如果 string
在所有位都被读取之前结束;
eof_failure
- 如果 read
语句在完成位集文字的读取之前到达文件结尾,
integer_overflow_error
- 如果 bitset-literal 的 bits
值大于 huge(0_bits_kind)
;或
read_failure
- 如果读取语句失败。
program example_read_bitset
use stdlib_bitsets
implicit none
character(*), parameter :: &
bits_0 = 'S33B000000000000000000000000000000000', &
bits_1 = 'S33B000000000000000000000000000000001', &
bits_2 = 'S33B100000000000000000000000000000000'
character(:), allocatable :: test_0, test_1, test_2
integer :: unit, status
type(bitset_64) :: set0, set1, set2, set3, set4, set5
call set0%read_bitset(bits_0, status)
call set1%read_bitset(bits_1, status)
call set2%read_bitset(bits_2, status)
call set0%write_bitset(test_0, status)
call set1%write_bitset(test_1, status)
call set2%write_bitset(test_2, status)
if (bits_0 == test_0 .and. bits_1 == test_1 .and. &
bits_2 == test_2) then
write (*, *) 'READ_BITSET to WRITE_BITSET strings worked.'
end if
open (newunit=unit, file='test.txt', status='replace', &
form='formatted', action='write')
call set2%write_bitset(unit, advance='no')
call set1%write_bitset(unit, advance='no')
call set0%write_bitset(unit)
close (unit)
open (newunit=unit, file='test.txt', status='old', &
form='formatted', action='read')
call set3%read_bitset(unit, advance='no')
call set4%read_bitset(unit, advance='no')
call set5%read_bitset(unit)
if (set3 == set0 .and. set4 == set1 .and. set5 == set2) then
write (*, *) 'WRITE_BITSET to READ_BITSET through unit worked.'
end if
end program example_read_bitset
set
- 将一个或多个位序列设置为 1实验性
将 self
中的一个或多个位序列设置为 1。
如果 start_pos
和 end_pos
不存在,则将 self
中位置 pos
处的位设置为 1。
如果 start_pos
和 end_pos
存在,且 end_pos >= start_pos
,则将 self
中从 start_pos
到 end_pos
的位置处的位设置为 1。
如果 start_pos
和 end_pos
存在,且 end_pos < start_pos
,则 self
保持不变。
超出范围 0 到 bits(self)
的位置将被忽略。
call self %
set (POS)
或
call self %
set (START_POS, END_POS)
元素子例程
self
: 应为类 bitset_type
的标量变量。它是一个 intent(inout)
参数。
pos
(可选): 应为一个标量整型表达式,其种类为 bits_kind
。它是一个 intent(in)
参数。
start_pos
(可选): 应为一个标量整型表达式,其种类为 bits_kind
。它是一个 intent(in)
参数。
end_pos
(可选): 应为一个标量整型表达式,其种类为 bits_kind
。它是一个 intent(in)
参数。
program example_set
use stdlib_bitsets
implicit none
type(bitset_large) :: set0
call set0%init(166)
if (set0%none()) write (*, *) 'SET0 is properly initialized.'
call set0%set(165)
if (set0%test(165)) write (*, *) 'Bit 165 is set.'
call set0%set(0, 164)
if (set0%all()) write (*, *) 'All bits are set.'
end program example_set
test
- 确定位是否已设置实验性
确定 self
中位置 pos
处的位是否已设置为 1。
result = self %
test (pos)
元素函数。
self
: 应为类 bitset_type
的标量表达式。它是一个 intent(in)
参数。
pos
: 应为 kind 为 bits_kind
的整数标量表达式。它是一个 intent(in)
参数。
结果是一个默认逻辑标量。如果 self
中 pos
处的位已设置,则结果为 .true.
,否则结果为 .false.
。如果 pos
超出范围 0... bits(self)-1
,则结果为 .false.
。
program example_test
use stdlib_bitsets
implicit none
type(bitset_large) :: set0
call set0%init(166)
call set0%not()
if (set0%all()) write (*, *) 'SET0 is properly initialized.'
call set0%clear(165)
if (.not. set0%test(165)) write (*, *) 'Bit 165 is cleared.'
call set0%set(165)
if (set0%test(165)) write (*, *) 'Bit 165 is set.'
end program example_test
to_string
- 将位集表示为二进制文字实验性
将 self
的值表示为 string
中的二进制文字。
call self %
to_string (string[, status])
子例程
self
: 应为类 bitset_type
的标量表达式。它是一个 intent(in)
参数。
string
: 应为一个标量默认字符变量,其长度可分配。它是一个 intent(out)
参数。在返回时,其应具有位集 self
的 binary-literal 表示形式。
status
(可选): 应为一个标量默认整型变量。它是一个 intent(out)
参数。如果存在,则其应具有 success
或 alloc_fault
的值。如果不存在,并且其应具有 alloc_fault
的值,则处理将停止,并使用信息性测试作为停止代码。这些值具有以下含义
success
- 未发现问题。
alloc_fault
- string
的分配失败。
program example_to_string
use stdlib_bitsets
implicit none
character(*), parameter :: &
bits_all = '111111111111111111111111111111111'
type(bitset_64) :: set0
character(:), allocatable :: new_string
call set0%init(33)
call set0%not()
call set0%to_string(new_string)
if (new_string == bits_all) then
write (*, *) "TO_STRING transferred BITS0 properly"// &
" into NEW_STRING."
end if
end program example_to_string
value
- 确定位的数值实验性
确定 self
中位置 pos
处的位的数值。
result = self %
value (pos)
元素函数。
self
: 应为类 bitset_type
的标量表达式。它是一个 intent(in)
参数。
pos
: 应为 kind 为 bits_kind
的整数标量表达式。它是一个 intent(in)
参数。
结果是一个默认整型标量。如果 self
中 pos
处的位已设置,则结果为 1,否则结果为 0。如果 pos
超出范围 0... bits(set)-1
,则结果为 0。
program example_value
use stdlib_bitsets
implicit none
type(bitset_large) :: set0
call set0%init(166)
call set0%not()
if (set0%all()) write (*, *) 'SET0 is properly initialized.'
call set0%clear(165)
if (set0%value(165) == 0) write (*, *) 'Bit 165 is cleared.'
call set0%set(165)
if (set0%value(165) == 1) write (*, *) 'Bit 165 is set.'
end program example_value
write_bitset
- 写入 bitset-literal实验性
将表示self
当前值的bitset-literal写入字符字符串或格式化文件。
call self %
write_bitset (string[, status])
或
call self %
write_bitset (unit[, advance, status])
子例程
self
: 应为类 bitset_type
的标量表达式。它是一个 intent(in)
参数。
string
(可选):应为可分配长度的标量默认字符变量。它是intent(out)
参数。
unit
(可选):应为标量默认逻辑表达式。它是intent(in)
参数。其值必须为具有write
或readwrite
访问权限的打开格式化文件的I/O单元号。
advance
(可选):应为标量默认字符表达式。它是intent(in)
参数。它是写入unit
的advance
说明符。如果存在,它必须具有'yes'
或'no'
的值。它的默认值为'yes'
。
如果advance
不存在或存在值为'no'
,则将bitset的bitset-literal写入unit
,后跟一个空格,并且当前记录不会前进。
如果advance
存在且值为'yes'
,则将bitset的bitset-literal写入unit
,并且记录会立即前进。
status
(可选):应为标量默认整数变量。它是intent(out)
参数。如果存在,则返回时应具有模块错误代码之一的值。如果不存在并且发现问题,处理将停止,并显示信息性停止代码。它可能具有以下错误代码值
success
- 未发现问题
alloc_fault
- 字符串的分配失败
write_failure
- 写入unit
失败
program example_write_bitset
use stdlib_bitsets
implicit none
character(*), parameter :: &
bits_0 = 'S33B000000000000000000000000000000000', &
bits_1 = 'S33B000000000000000000000000000000001', &
bits_2 = 'S33B100000000000000000000000000000000'
character(:), allocatable :: test_0, test_1, test_2
integer :: unit, status
type(bitset_64) :: set0, set1, set2, set3, set4, set5
call set0%read_bitset(bits_0, status)
call set1%read_bitset(bits_1, status)
call set2%read_bitset(bits_2, status)
call set0%write_bitset(test_0, status)
call set1%write_bitset(test_1, status)
call set2%write_bitset(test_2, status)
if (bits_0 == test_0 .and. bits_1 == test_1 .and. &
bits_2 == test_2) then
write (*, *) 'READ_BITSET to WRITE_BITSET strings worked.'
end if
open (newunit=unit, file='test.txt', status='replace', &
form='formatted', action='write')
call set2%write_bitset(unit, advance='no')
call set1%write_bitset(unit, advance='no')
call set0%write_bitset(unit)
close (unit)
open (newunit=unit, file='test.txt', status='old', &
form='formatted', action='read')
call set3%read_bitset(unit, advance='no')
call set4%read_bitset(unit, advance='no')
call set5%read_bitset(unit)
if (set3 == set0 .and. set4 == set1 .and. set5 == set2) then
write (*, *) 'WRITE_BITSET to READ_BITSET through unit worked.'
end if
end program example_write_bitset
xor
- 按位异或实验性
将set1
的bitset替换为set1
的原始位与set2
的原始位按位异或的结果。注意set1
和set2
必须具有相同数量的位,否则结果未定义。
result =
xor (set1, set2)
元素子例程
set1
:应为标量bitset_64
或bitset_large
变量。它是intent(inout)
参数。返回时,set1
中位的的值是set1
中的原始位与set2
中对应位按位异或的结果。
set2
应为与set1
类型相同的标量表达式。它是intent(in)
参数。注意set1
和set2
必须具有相同数量的位,否则结果未定义。
program example_xor
use stdlib_bitsets
implicit none
type(bitset_large) :: set0, set1
call set0%init(166)
call set1%init(166)
call xor(set0, set1) ! none none
if (set0%none()) write (*, *) 'First test of XOR worked.'
call set0%not()
call xor(set0, set1) ! all none
if (set0%all()) write (*, *) 'Second test of XOR worked.'
call set0%not()
call set1%not()
call xor(set0, set1) ! none all
if (set0%all()) write (*, *) 'Third test of XOR worked.'
call set0%not()
call xor(set0, set1) ! all all
if (set0%none()) write (*, *) 'Fourth test of XOR worked.'
end program example_xor
stdlib_bitsets
运算符的规范==
- 比较两个bitset以确定位的值是否相同实验性
如果set1
和set2
中的所有位都具有相同的值,则返回.true.
,否则返回.false.
。
result = set1
[[stdlib_bitsets(module):==(interface)]] set2
或
result = set1 .EQ. set2
元素运算符
set1
:应为标量bitset_64
或bitset_large
表达式。它是intent(in)
参数。
set2
:应为与self
类型相同的标量表达式。它将与set1
具有相同数量的位。它是intent(in)
参数。
结果是默认逻辑标量。如果两个bitset中的位都设置为相同的值,则结果为.true.
,否则结果为.false.
。
program example_equality
use stdlib_bitsets
implicit none
type(bitset_64) :: set0, set1, set2
call set0%init(33)
call set1%init(33)
call set2%init(33)
call set1%set(0)
call set2%set(32)
if (set0 == set0 .and. set1 == set1 .and. set2 == set2 .and. &
.not. set0 == set1 .and. .not. set0 == set2 .and. .not. &
set1 == set2) then
write (*, *) 'Passed 64 bit equality tests.'
else
error stop 'Failed 64 bit equality tests.'
end if
end program example_equality
/=
- 比较两个bitset以确定任何位的值是否不同实验性
如果self
和set2
中的任何位的值不同,则返回.true.
,否则返回.false.
。
result = set1
[[stdlib_bitsets(module):/=(interface)]] set2
或
result = set1 .NE. set2
元素函数
set1
:应为标量bitset_64
或bitset_large
表达式。它是intent(in)
参数。
set2
:应为与self
类型相同的标量表达式。它将与set1
具有相同数量的位。它是intent(in)
参数。
结果是默认逻辑标量。如果两个bitset中的任何位不同,则结果为.true.
,否则结果为.false.
。
program example_inequality
use stdlib_bitsets
implicit none
type(bitset_64) :: set0, set1, set2
call set0%init(33)
call set1%init(33)
call set2%init(33)
call set1%set(0)
call set2%set(32)
if (set0 /= set1 .and. set0 /= set2 .and. set1 /= set2 .and. &
.not. set0 /= set0 .and. .not. set1 /= set1 .and. .not. &
set2 /= set2) then
write (*, *) 'Passed 64 bit inequality tests.'
else
error stop 'Failed 64 bit inequality tests.'
end if
end program example_inequality
>=
- 比较两个bitset以确定第一个是否大于或等于第二个实验性
如果set1
和set2
中的位相同,或者最高阶不同的位在set1
中设置为1,在set2
中设置为0,则返回.true.
,否则返回.false.
。集合的大小必须相同,否则结果未定义。
result = set1
[[stdlib_bitsets(module):>=(interface)]] set2
或
result = set1 .GE. set2
元素运算符
set1
:应为标量bitset_64
或bitset_large
表达式。它是intent(in)
参数。
set2
:应为与self
类型相同的标量表达式。它将与set1
具有相同数量的位。它是intent(in)
参数。
结果是默认逻辑标量。如果set1
和set2
中的位相同,或者最高阶不同的位在set1
中设置为1,在set2
中设置为0,则结果为.true.
,否则结果为.false.
。
program example_ge
use stdlib_bitsets
implicit none
type(bitset_64) :: set0, set1, set2
call set0%init(33)
call set1%init(33)
call set2%init(33)
call set1%set(0)
call set2%set(32)
if (set1 >= set0 .and. set2 >= set1 .and. set2 >= set0 .and. &
set0 >= set0 .and. set1 >= set1 .and. set2 >= set2 .and. &
.not. set0 >= set1 .and. .not. set0 >= set2 .and. .not. &
set1 >= set2) then
write (*, *) 'Passed 64 bit greater than or equals tests.'
else
error stop 'Failed 64 bit greater than or equals tests.'
end if
end program example_ge
>
- 比较两个bitset以确定第一个是否大于另一个实验性
如果set1
和set2
中的位不同,并且最高阶不同的位在set1
中设置为1,在set2
中设置为0,则返回.true.
,否则返回.false.
。集合的大小必须相同,否则结果未定义。
result = set1
[[stdlib_bitsets(module):>(interface)]] set2
或
result = set1 .GT. set2
元素运算符
set1
:应为标量bitset_64
或bitset_large
表达式。它是intent(in)
参数。
set2
:应为与self
类型相同的标量表达式。它将与set1
具有相同数量的位。它是intent(in)
参数。
结果是默认逻辑标量。如果set1
和set2
中的位不同,并且最高阶不同的位在set1
中设置为1,在set2
中设置为0,则结果为.true.
,否则结果为.false.
。
program example_gt
use stdlib_bitsets
implicit none
type(bitset_64) :: set0, set1, set2
call set0%init(33)
call set1%init(33)
call set2%init(33)
call set1%set(0)
call set2%set(32)
if (set1 > set0 .and. set2 > set1 .and. set2 > set0 .and. &
.not. set0 > set0 .and. .not. set0 > set1 .and. .not. &
set1 > set2) then
write (*, *) 'Passed 64 bit greater than tests.'
else
error stop 'Failed 64 bit greater than tests.'
end if
end program example_gt
<=
- 比较两个bitset以确定第一个是否小于或等于另一个实验性
如果set1
和set2
中的位相同,或者最高阶不同的位在set1
中设置为0,在set2
中设置为1,则返回.true.
,否则返回.false.
。集合的大小必须相同,否则结果未定义。
result = set1
[[stdlib_bitsets(module):<=(interface)]] set2
或
result = set1 .LE. set2
元素运算符
set1
:应为标量bitset_64
或bitset_large
表达式。它是intent(in)
参数。
set2
:应为与self
类型相同的标量表达式。它将与set1
具有相同数量的位。它是intent(in)
参数。
结果是默认逻辑标量。如果set1
和set2
中的位相同,或者最高阶不同的位在set1
中设置为0,在set2
中设置为1,则结果为.true.
,否则结果为.false.
。
program example_le
use stdlib_bitsets
implicit none
type(bitset_64) :: set0, set1, set2
call set0%init(33)
call set1%init(33)
call set2%init(33)
call set1%set(0)
call set2%set(32)
if (set0 <= set1 .and. set1 <= set2 .and. set0 <= set2 .and. &
set0 <= set0 .and. set1 <= set1 .and. set2 <= set2 .and. &
.not. set1 <= set0 .and. .not. set2 <= set0 .and. .not. &
set2 <= set1) then
write (*, *) 'Passed 64 bit less than or equal tests.'
else
error stop 'Failed 64 bit less than or equal tests.'
end if
end program example_le
<
- 比较两个bitset以确定第一个是否小于另一个实验性
如果set1
和set2
中的位不同,并且最高阶不同的位在set1
中设置为0,在set2
中设置为1,则返回.true.
,否则返回.false.
。集合的大小必须相同,否则结果未定义。
result = set1
[[stdlib_bitsets(module):<(interface)]] set2
或
`result = set1 .LT. set2
元素运算符
set1
:应为标量bitset_64
或bitset_large
表达式。它是intent(in)
参数。
set2
:应为与self
类型相同的标量表达式。它将与set1
具有相同数量的位。它是intent(in)
参数。
结果是默认逻辑标量。如果set1
和set2
中的位不同,并且最高阶不同的位在set1
中设置为0,在set2
中设置为1,则结果为.true.
,否则结果为.false.
。
program example_lt
use stdlib_bitsets
implicit none
type(bitset_64) :: set0, set1, set2
call set0%init(33)
call set1%init(33)
call set2%init(33)
call set1%set(0)
call set2%set(32)
if (set0 < set1 .and. set1 < set2 .and. set0 < set2 .and. &
.not. set0 < set0 .and. .not. set2 < set0 .and. .not. &
set2 < set1) then
write (*, *) 'Passed 64 bit less than tests.'
else
error stop 'Failed 64 bit less than tests.'
end if
end program example_lt