概要
Fortranが標準で備えているビット演算やビット操作,比較,変換などをまとめました.
本記事で紹介している機能一覧は下記の通りです.
- 演算
- シフト
- 比較
- 変換・操作
- 特性値の取得
環境
- Windows 10 64 bit
- Windows 11 64 bit
- gfortran 10.3, 11.2
- Intel Fortran classic 2021.5.0
- NAG Fortran 7.1.0
Fortran 2023での拡張
本記事はFortran 2018規格に沿って記述していますが,Fortran 20203において,2進(および8進,16進)定数の取り扱いが拡張されることになりました.
本記事に関係するところでは,2進定数そのままでは代入演算子の右辺とすることができなかったのが,下記の場合にそのまま右辺とすることができるようになりました.
- 整数あるいは実数の名前付きオブジェクトの初期化
- 整数あるいは実数への組み込み代入演算
- 整数あるいは実数の配列構成子内
-
enum
の整数値
表示
ビットに着目するからには,変数を2進数で表示できる必要があります.Fortranでは変数を2進数で表示することも,2進数で表現した数値リテラルを変数に代入することもできます.
数値リテラルとして取り扱う場合は,基数を表す記号の後ろに数値を文字列として記述します.
基数 | 基数を表す記号 | 表記例 |
---|---|---|
2 | B |
B'1111100111' |
2進数表記では,それが表す数値の型が不明なので,型変換用の関数と併用する必要があります.
! これは許可されない
! print '(I4)', B'1111100111'
print *, int(B'1111100111') ! 999
print *, real(B'1111100111') ! 1.3998972E-42
変数に2進数リテラルを代入する場合も同様です.
program main
use, intrinsic :: iso_fortran_env
implicit none
integer(int32) :: i
real(real32) :: r
! これは許可されないが,Fortran 2023からは許可される
! i = B'1111100111'
! r = B'1111100111'
i = int(B'1111100111')
r = real(B'1111100111')
print *, i, r ! 999 1.3998972E-42
end program main
2進数で表示する場合には,print
文もしくはwrite
文の書式で指定します.上位ビットが0の場合は表示が省略されます.その場合は,書式指定で.
の後ろに表示する桁数を記述します.
基数 | 書式例 | 記述例 | 表示結果 |
---|---|---|---|
2 | '(B8)' |
print '(B8)', 100_int8 |
1100100 |
2 | '(B8.8)' |
print '(B8.8)', 100_int8 |
01100100 |
ここでは2進数についてのみ述べましたが,8進数,16進数も同様に取り扱う事ができます.基数を表す記号は,8進数の場合はO
,16進数の場合はZ
で,2, 8, 16進数をまとめてBOZリテラルとよばれます.
基数 | 基数を表す記号 | 表記例 |
---|---|---|
2 | B |
B'1111100111' |
8 | O |
O'12345670' |
16 | Z |
Z'A1B2' |
演算
ここでは,2項もしくは単項演算を行う手続を紹介します.
iand
二つの整数型変数,整数リテラル,あるいはBOZリテラルのビットごとの論理積を計算し,結果を整数で返します.
書式
-
result = iand(i, j)
-
i
,j
は整数(1, 2, 4, 8バイト)もしくはBOZリテラル.-
i
,j
のどちらもBOZリテラルであってはならない. -
i
,j
の整数kindは同じでなければならない. -
i
,j
は配列でもよい.
-
-
result
は整数.-
i
が整数ならi
と同じkind,そうでなければj
と同じkind. -
i
,j
が配列の場合,result
はi
,j
と同じ次元,要素数の配列.
-
-
結果の値は,ビットごとに下記の真理値表に従って計算されます.
i |
j |
iand(i,j) |
---|---|---|
0 |
0 |
0 |
1 |
0 |
0 |
0 |
1 |
0 |
1 |
1 |
1 |
例
program main
use, intrinsic :: iso_fortran_env
implicit none
integer(int8) :: i, j
i = int(B'10101010', kind=int8)
j = int(B'01010101', kind=int8)
print '(B8.8)', iand(i, j) ! 00000000
end program main
program main
use, intrinsic :: iso_fortran_env
implicit none
integer(int32) :: i, j
i = int(B'1111')
j = int(B'1111')
print '(B32.32)', iand(i, j) ! 00000000000000000000000000001111
end program main
program main
implicit none
print '(B32.32)', iand( B'11110000000000000000000000000000', &
int(B'11110000000000000000000000000000'))
! 11110000000000000000000000000000
end program main
program main
use, intrinsic :: iso_fortran_env
implicit none
integer(int8), allocatable :: i(:), j(:)
i = [integer(int8) :: 125, 126, 127]
j = [integer(int8) :: 15, 15, 15]
print '(*(B8.8:," "))', i ! 01111101 01111110 01111111
print '(*(B8.8:," "))', j ! 00001111 00001111 00001111
print '(*(B8.8:," "))', iand(i, j) ! 00001101 00001110 00001111
end program main
ior
二つの整数型変数,整数リテラル,あるいはBOZリテラルのビットごとの包含的論理和(1と1の論理和が1)を計算し,結果を整数で返します.
書式
-
result = ior(i, j)
-
i
,j
は整数(1, 2, 4, 8バイト)もしくはBOZリテラル.-
i
,j
のどちらもBOZリテラルであってはならない. -
i
,j
の整数kindは同じでなければならない. -
i
,j
は配列でもよい.
-
-
result
は整数.-
i
が整数ならi
と同じkind,そうでなければj
と同じkind. -
i
,j
が配列の場合,result
はi
,j
と同じ次元,要素数の配列.
-
-
結果の値は,ビットごとに下記の真理値表に従って計算されます.
i |
j |
ior(i,j) |
---|---|---|
0 |
0 |
0 |
1 |
0 |
1 |
0 |
1 |
1 |
1 |
1 |
1 |
例
program main
use, intrinsic :: iso_fortran_env
implicit none
integer(int8) :: i, j
i = int(B'10101011', kind=int8)
j = int(B'01010101', kind=int8)
print '(B8.8)', ior(i, j) ! 11111111
end program main
program main
use, intrinsic :: iso_fortran_env
implicit none
integer(int32) :: i
i = int(B'1010')
print '(B32.32)', ior(i, B'1101') ! 00000000000000000000000000001111
end program main
program main
use, intrinsic :: iso_fortran_env
implicit none
integer(int8), allocatable :: i(:), j(:)
i = [integer(int8) :: 125, 126, 127]
j = [integer(int8) :: 15, 15, 15]
print '(*(B8.8:," "))', i ! 01111101 01111110 01111111
print '(*(B8.8:," "))', j ! 00001111 00001111 00001111
print '(*(B8.8:," "))', ior(i, j) ! 01111111 01111111 01111111
end program main
ieor
二つの整数型変数,整数リテラル,あるいはBOZリテラルのビットごとの排他的論理和(1と1の論理和が0)を計算し,結果を整数で返します.
書式
-
result = ieor(i, j)
-
i
,j
は整数(1, 2, 4, 8バイト)もしくはBOZリテラル.-
i
,j
のどちらもBOZリテラルであってはならない. -
i
,j
の整数kindは同じでなければならない. -
i
,j
は配列でもよい.
-
-
result
は整数.-
i
が整数ならi
と同じkind,そうでなければj
と同じkind. -
i
,j
が配列の場合,result
はi
,j
と同じ次元,要素数の配列.
-
-
結果の値は,ビットごとに下記の真理値表に従って計算されます.
i |
j |
ieor(i,j) |
---|---|---|
0 |
0 |
0 |
1 |
0 |
1 |
0 |
1 |
1 |
1 |
1 |
0 |
例
program main
use, intrinsic :: iso_fortran_env
implicit none
integer(int8) :: i, j
i = int(B'10101011', kind=int8)
j = int(B'01010101', kind=int8)
print '(B8.8)', ieor(i, j) ! 11111110
end program main
program main
use, intrinsic :: iso_fortran_env
implicit none
integer(int32) :: i
i = int(B'1010')
print '(B32.32)', ieor(i, B'1101') ! 00000000000000000000000000000111
end program main
program main
use, intrinsic :: iso_fortran_env
implicit none
integer(int8), allocatable :: i(:), j(:)
i = [integer(int8) :: 125, 126, 127]
j = [integer(int8) :: 15, 15, 15]
print '(*(B8.8:," "))', i ! 01111101 01111110 01111111
print '(*(B8.8:," "))', j ! 00001111 00001111 00001111
print '(*(B8.8:," "))', ieor(i, j) ! 01110010 01110001 01110000
end program main
not
整数型変数,整数リテラルの論理否定を計算し,結果を整数で返します.
書式
-
result = not(i)
-
i
は整数(1, 2, 4, 8バイト).-
i
は配列でもよい.
-
-
result
は整数.-
i
と同じkind. -
i
が配列の場合,result
はi
と同じ次元,要素数の配列.
-
-
結果の値は,ビットごとに下記の真理値表に従って計算されます.
i |
not(i) |
---|---|
0 |
1 |
1 |
0 |
例
program main
use, intrinsic :: iso_fortran_env
implicit none
integer(int8) :: i
i = int(B'10101010', kind=int8)
print '(B8.8)', not(i) ! 01010101
end program main
program main
use, intrinsic :: iso_fortran_env
implicit none
integer(int8), allocatable :: i(:)
i = [integer(int8) :: 2, 4, 8]
print '(*(B8.8:," "))', i ! 00000010 00000100 00001000
print '(*(B8.8:," "))', not(i) ! 11111101 11111011 11110111
end program main
iall
整数型配列を構成する全要素について,ビットごとの論理積を計算し,結果を整数型配列で返します.
簡単に,全要素のiand
,あるいは次元ごとのiand
を計算すると考えてもらっても問題ありません.
書式
-
result = iall(array [, dim] [, mask])
-
array
は整数(1, 2, 4, 8バイト)型配列. -
dim
は整数で,1以上array
の配列次元数以下の値.- 省略された場合,
array
を1次元配列として処理する.
- 省略された場合,
-
mask
は論理型で,array
と同じ形状の配列. -
result
は整数型配列あるいはスカラ.- kindは
array
と同じ. - 配列次元は,
array
の次元-1. -
array
が1次元あるいはdim
が省略された場合はスカラ.
- kindは
-
例
program main
use, intrinsic :: iso_fortran_env
implicit none
integer(int8), allocatable :: a(:)
a = [integer(int8) :: int(B'1110'), int(B'1101'), int(B'1011')]
print '(*(B4.4:, " "))', a ! 1110 1101 1011
print '(*(B4.4:, " "))', iall(a) ! 1000
end program main
program main
use, intrinsic :: iso_fortran_env
implicit none
integer(int8), allocatable :: a(:)
a = [integer(int8) :: int(B'1110'), int(B'1101'), int(B'1011')]
print '(*(B4.4:, " "))', a ! 1110 1101 1011
print '(*(B4.4:, " "))', iall(a, mask=[.true., .false., .true.]) ! 1010
end program main
program main
use, intrinsic :: iso_fortran_env
implicit none
integer(int8), allocatable :: a(:, :)
a = reshape([integer(int8) :: &
int(B'00001110'), int(B'00001101'), int(B'00001011'), &
int(B'01111011'), int(B'01111110'), int(B'01111101')], &
[3, 2])
print '(*(B8.8:, " "))', a ! 00001110 00001101 00001011 01111011 01111110 01111101
print '(*(B8.8:, " "))', iall(a) ! 00001000
! 全要素のiandを計算
end program main
program main
use, intrinsic :: iso_fortran_env
implicit none
integer(int8), allocatable :: a(:, :)
a = reshape([integer(int8) :: &
int(B'00001110'), int(B'00001101'), int(B'00001011'), &
int(B'01111011'), int(B'01111110'), int(B'01111101')], &
[3, 2])
print '(*(B8.8:, " "))', a ! 00001110 00001101 00001011 01111011 01111110 01111101
print '(*(B8.8:, " "))', iall(a, dim=1) ! 00001000 01111000
! iandを→方向に計算 int(B'00001110'), int(B'00001101'), int(B'00001011')
! iandを→方向に計算 int(B'01111011'), int(B'01111110'), int(B'01111101')
end program main
program main
use, intrinsic :: iso_fortran_env
implicit none
integer(int8), allocatable :: a(:, :)
a = reshape([integer(int8) :: &
int(B'00001110'), int(B'00001101'), int(B'00001011'), &
int(B'01111011'), int(B'01111110'), int(B'01111101')], &
[3, 2])
print '(*(B8.8:, " "))', a ! 00001110 00001101 00001011 01111011 01111110 01111101
print '(*(B8.8:, " "))', iall(a, dim=2) ! 00001010 00001100 00001001
! iandを↓方向に計算 iandを↓方向に計算 iandを↓方向に計算
! int(B'00001110'), int(B'00001101'), int(B'00001011')
! int(B'01111011'), int(B'01111110'), int(B'01111101')
end program main
iany
整数型配列を構成する全要素について,ビットごとの包含的論理和を計算し,結果を整数型配列で返します.
簡単に,全要素のior
,あるいは次元ごとのior
を計算すると考えてもらっても問題ありません.
書式
-
result = iany(array [, dim] [, mask])
-
array
は整数(1, 2, 4, 8バイト)型配列. -
dim
は整数で,1以上array
の配列次元数以下の値.- 省略された場合,
array
を1次元配列として処理する.
- 省略された場合,
-
mask
は論理型で,array
と同じ形状の配列. -
result
は整数型配列あるいはスカラ.- kindは
array
と同じ. - 配列次元数は,
array
の次元-1. -
array
が1次元あるいはdim
が省略された場合はスカラ.
- kindは
-
例
program main
use, intrinsic :: iso_fortran_env
implicit none
integer(int32), allocatable :: a(:)
a = [int(B'1001'), int(B'0101'), int(B'0011')]
print '(*(B4.4:, " "))', a ! 1001 0101 0011
print '(*(B4.4:, " "))', iany(a) ! 1111
end program main
program main
use, intrinsic :: iso_fortran_env
implicit none
integer(int32), allocatable :: a(:)
a = [int(B'1001'), int(B'0101'), int(B'0011')]
print '(*(B4.4:, " "))', a ! 1001 0101 0011
print '(*(B4.4))', iany(a, mask=[.true., .false., .true.]) ! 1011
end program main
program main
use, intrinsic :: iso_fortran_env
implicit none
integer(int8), allocatable :: a(:, :)
a = reshape([integer(int8) :: &
int(B'00001110'), int(B'00001101'), int(B'00001011'), &
int(B'01001011'), int(B'00011110'), int(B'00101101')], &
[3, 2])
print '(*(B8.8:, " "))', a ! 00001110 00001101 00001011 01001011 00011110 00101101
print '(*(B8.8:, " "))', iany(a) ! 01111111
! 全要素のiorを計算
end program main
program main
use, intrinsic :: iso_fortran_env
implicit none
integer(int8), allocatable :: a(:, :)
a = reshape([integer(int8) :: &
int(B'00001110'), int(B'00001101'), int(B'00001011'), &
int(B'01001011'), int(B'00011110'), int(B'00101101')], &
[3, 2])
print '(*(B8.8:, " "))', a ! 00001110 00001101 00001011 01001011 00011110 00101101
print '(*(B8.8:, " "))', iany(a, dim=1) ! 00001111 01111111
! ianyを→方向に計算 int(B'00001110'), int(B'00001101'), int(B'00001011')
! ianyを→方向に計算 int(B'01001011'), int(B'00011110'), int(B'00101101')
end program main
program main
use, intrinsic :: iso_fortran_env
implicit none
integer(int8), allocatable :: a(:, :)
a = reshape([integer(int8) :: &
int(B'00001110'), int(B'00001101'), int(B'00001011'), &
int(B'01001011'), int(B'00011110'), int(B'00101101')], &
[3, 2])
print '(*(B8.8:, " "))', a ! 00001110 00001101 00001011 01001011 00011110 00101101
print '(*(B8.8:, " "))', iany(a, dim=2) ! 01001111 00011111 00101111
! ianyを↓方向に計算 ianyを↓方向に計算 ianyを↓方向に計算
! int(B'00001110'), int(B'00001101'), int(B'00001011')
! int(B'01001011'), int(B'00011110'), int(B'00101101')
end program main
iparity
整数型配列を構成する全要素について,ビットごとの排他的論理和を計算し,結果を整数型配列で返します.
簡単に,全要素のieor
,あるいは次元ごとのieor
を計算すると考えてもらっても問題ありません.
書式
-
result = iparity(array [, dim] [, mask])
-
array
は整数(1, 2, 4, 8バイト)型配列. -
dim
は整数で,1以上array
の配列次元数以下の値.- 省略された場合,
array
を1次元配列として処理する.
- 省略された場合,
-
mask
は論理型で,array
と同じ形状の配列. -
result
は整数型配列あるいはスカラ.- kindは
array
と同じ. - 配列次元数は,
array
の次元-1. -
array
が1次元あるいはdim
が省略された場合はスカラ.
- kindは
-
例
program main
use, intrinsic :: iso_fortran_env
implicit none
integer(int32), allocatable :: a(:)
a = [int(B'1001'), int(B'0101'), int(B'0011')]
print '(*(B4.4:, " "))', a ! 1001 0101 0011
print '(*(B4.4))', iparity(a) ! 1111
end program main
program main
use, intrinsic :: iso_fortran_env
implicit none
integer(int32), allocatable :: a(:)
a = [int(B'1001'), int(B'0101'), int(B'0011')]
print '(*(B4.4:, " "))', a ! 1001 0101 0011
print '(*(B4.4))', iparity(a, mask=[.true., .false., .true.]) ! 1010
end program main
program main
use, intrinsic :: iso_fortran_env
implicit none
integer(int8), allocatable :: a(:, :)
a = reshape([integer(int8) :: &
int(B'00001110'), int(B'00001101'), int(B'00001011'), &
int(B'01001011'), int(B'00011110'), int(B'00101101')], &
[3, 2])
print '(*(B8.8:, " "))', a ! 00001110 00001101 00001011 01001011 00011110 00101101
print '(*(B8.8:, " "))', iparity(a) ! 01110000
! 全要素のieorを計算
end program main
program main
use, intrinsic :: iso_fortran_env
implicit none
integer(int8), allocatable :: a(:, :)
a = reshape([integer(int8) :: &
int(B'00001110'), int(B'00001101'), int(B'00001011'), &
int(B'01001011'), int(B'00011110'), int(B'00101101')], &
[3, 2])
print '(*(B8.8:, " "))', a ! 00001110 00001101 00001011 01001011 00011110 00101101
print '(*(B8.8:, " "))', iparity(a, dim=1) ! 00001000 01111000
! iparityを→方向に計算 int(B'00001110'), int(B'00001101'), int(B'00001011')
! iparityを→方向に計算 int(B'01001011'), int(B'00011110'), int(B'00101101')
end program main
program main
use, intrinsic :: iso_fortran_env
implicit none
integer(int8), allocatable :: a(:, :)
a = reshape([integer(int8) :: &
int(B'00001110'), int(B'00001101'), int(B'00001011'), &
int(B'01001011'), int(B'00011110'), int(B'00101101')], &
[3, 2])
print '(*(B8.8:, " "))', a ! 00001110 00001101 00001011 01001011 00011110 00101101
print '(*(B8.8:, " "))', iparity(a, dim=2) ! 01000101 00010011 00100110
! iparityを↓方向に計算 iparityを↓方向に計算 iparityを↓方向に計算
! int(B'00001110'), int(B'00001101'), int(B'00001011')
! int(B'01001011'), int(B'00011110'), int(B'00101101')
end program main
parity
論理型配列を構成する全要素の.neqv.
,あるいは次元ごとの.neqv.
を計算した結果を論理値で返します.
簡単に,論理型配列内の真の要素が奇数個の場合に真,偶数個の場合に偽を返すと考えてもらっても問題ありません.
書式
-
result = parity(array [, dim])
-
array
は論理型配列. -
dim
は整数で,1以上array
の配列次元数以下の値.- 省略された場合,
array
を1次元配列として処理する.
- 省略された場合,
-
result
は論理型配列あるいはスカラ.- 配列次元数は,
array
の次元-1. -
array
が1次元あるいはdim
が省略された場合はスカラ.
- 配列次元数は,
-
例
program main
use, intrinsic :: iso_fortran_env
implicit none
logical, allocatable :: a(:)
a = [.true., .false., .true.]
print '(*(L1:, " "))', a ! T F T
print '(*(L1:, " "))', parity(a) ! F
end program main
``Fortran
program main
use, intrinsic :: iso_fortran_env
implicit none
logical, allocatable :: a(:)
a = [.true., .false., .true.]
print '(*(L1:, " "))', a ! F T F
print '(*(L1:, " "))', parity(a) ! T
end program main
``Fortran
program main
use, intrinsic :: iso_fortran_env
implicit none
logical, allocatable :: a(:, :)
a = reshape([.true., .false., .true., &
.false., .true., .false.], &
[3, 2])
print '(*(L1:, " "))', a ! T F T F T F
print '(*(L1:, " "))', parity(a) ! T
end program main
``Fortran
program main
use, intrinsic :: iso_fortran_env
implicit none
logical, allocatable :: a(:, :)
a = reshape([.true., .false., .true., &
.false., .true., .false.], &
[3, 2])
print '(*(L1:, " "))', a ! T F T F T F
print '(*(L1:, " "))', parity(a, dim=1) ! F T
end program main
``Fortran
program main
use, intrinsic :: iso_fortran_env
implicit none
logical, allocatable :: a(:, :)
a = reshape([.true., .false., .true., &
.false., .true., .false.], &
[3, 2])
print '(*(L1:, " "))', a ! T F T F T F
print '(*(L1:, " "))', parity(a, dim=2) ! T T T
end program main
シフト
ここでは,ビットシフトを行う手続を紹介します.
ishft
整数型変数あるいは整数リテラルを,右あるいは左方向に指定の桁だけビットシフトした値を整数で返します.左端あるいは右端からはみ出したビットは破棄され,反対側には0が設定されます.
書式
-
result = ishft(i, shift)
-
i
は整数(1, 2, 4, 8バイト).-
i
は配列でもよい.
-
-
shift
は整数で,その絶対値は1以上i
のビットサイズ以下の値.-
shift>0
の場合,左方向にシフトが行われる. -
shift<0
の場合,右方向にシフトが行われる. -
0
の場合,シフトは行われない. -
shift
は配列でもよい. -
i
とshift
の両方を配列とする場合,配列の形状は同じでなければならない.
-
-
result
は整数.- kindは
i
と同じ. -
i
が配列の場合,result
はi
と同じ次元,要素数の配列. -
shift
が配列の場合,result
はshift
と同じ次元,要素数の配列.
- kindは
-
例
program main
use, intrinsic :: iso_fortran_env
implicit none
integer(int8) :: i
i = int(B'11100111', kind=int8)
print '(*(B8.8:, " "))', ishft(i, 2) ! 10011100
print '(*(B8.8:, " "))', ishft(i, 0) ! 11100111
print '(*(B8.8:, " "))', ishft(i, -2) ! 00111001
end program main
ishftc
整数型変数あるいは整数リテラルを,右あるいは左方向に指定の桁だけビットシフトした値を返します.ビットシフトは循環的に行われ,左端あるいは右端からはみ出したビットは反対側に設定されます.
書式
-
result = ishftc(i, shift)
-
i
は整数(1, 2, 4, 8バイト).-
i
は配列でもよい.
-
-
shift
は整数で,その絶対値は1以上i
のビットサイズ以下の値.-
shift>0
の場合,左方向に循環シフトが行われる. -
shift<0
の場合,右方向に循環シフトが行われる. -
0
の場合,シフトは行われない. -
shift
は配列でもよい. -
i
とshift
の両方を配列とする場合,配列の形状は同じでなければならない.
-
-
result
は整数.- kindは
i
と同じ. -
i
が配列の場合,result
はi
と同じ次元,要素数の配列.
- kindは
-
例
program main
use, intrinsic :: iso_fortran_env
implicit none
integer(int8) :: i
i = int(B'11100111', kind=int8)
print '(*(B8.8:, " "))', ishftc(i, 2) ! 10011111
print '(*(B8.8:, " "))', ishftc(i, 0) ! 11100111
print '(*(B8.8:, " "))', ishftc(i, -2) ! 11111001
end program main
shifta
整数型変数あるいは整数リテラルを,指定の桁だけ右方向にビットシフトした値を返します.左端からはみ出したビットは破棄され,右のシフトされたビット分には,シフトされる整数の最上位ビットの値が詰められます.
書式
-
result = shifta(i, shift)
-
i
は整数(1, 2, 4, 8バイト).-
i
は配列でもよい.
-
-
shift
は整数で,1以上i
のビットサイズ以下の値.-
0
の場合,シフトは行われない. -
shift
は配列でもよい. -
i
とshift
の両方を配列とする場合,配列の形状は同じでなければならない.
-
-
result
は整数.- kindは
i
と同じ. -
i
が配列の場合,result
はi
と同じ次元,要素数の配列. -
shift
が配列の場合,result
はshift
と同じ次元,要素数の配列.
- kindは
-
例
program main
use, intrinsic :: iso_fortran_env
implicit none
integer(int8) :: i
i = int(B'10000000', kind=int8)
print '(*(B8.8:, " "))', shifta(i, 2) ! 11100000
end program main
program main
use, intrinsic :: iso_fortran_env
implicit none
integer(int8) :: i
i = int(B'01111111', kind=int8)
print '(*(B8.8:, " "))', shifta(i, 2) ! 00011111
end program main
shiftl
整数型変数あるいは整数リテラルを,指定の桁だけ左方向にビットシフトした値を返します.左端からはみ出したビットは破棄され,右側には0が詰められます.
書式
-
result = shiftl(i, shift)
-
i
は整数(1, 2, 4, 8バイト).-
i
は配列でもよい.
-
-
shift
は整数で,1以上i
のビットサイズ以下の値.-
0
の場合,シフトは行われない. -
shift
は配列でもよい. -
i
とshift
の両方を配列とする場合,配列の形状は同じでなければならない.
-
-
result
は整数.- kindは
i
と同じ. -
i
が配列の場合,result
はi
と同じ次元,要素数の配列. -
shift
が配列の場合,result
はshift
と同じ次元,要素数の配列.
- kindは
-
例
program main
use, intrinsic :: iso_fortran_env
implicit none
integer(int8) :: i
i = int(B'11111111', kind=int8)
print '(*(B8.8:, " "))', shiftl(i, 2) ! 11111100
end program main
shiftr
整数型変数あるいは整数リテラルを,指定の桁だけ右方向にビットシフトした値を返します.右端からはみ出したビットは破棄され,左側には0が詰められます.
書式
-
result = shiftl(i, shift)
-
i
は整数(1, 2, 4, 8バイト).-
i
は配列でもよい.
-
-
shift
は整数で,1以上i
のビットサイズ以下の値.-
0
の場合,シフトは行われない. -
shift
は配列でもよい. -
i
とshift
の両方を配列とする場合,配列の形状は同じでなければならない.
-
-
result
は整数.- kindは
i
と同じ. -
i
が配列の場合,result
はi
と同じ次元,要素数の配列. -
shift
が配列の場合,result
はshift
と同じ次元,要素数の配列.
- kindは
-
例
program main
use, intrinsic :: iso_fortran_env
implicit none
integer(int8) :: i
i = int(B'11111111', kind=int8)
print '(*(B8.8:, " "))', shiftr(i, 2) ! 00111111
end program main
比較
ここでは,ビット単位の比較を行う組み込み手続を紹介します.
bge
二つの整数型変数,整数リテラルあるいはBOZリテラルをビットごとに比較し,ビット列が大きいか等しいかを判別した結果を論理値で返します.この比較において,最上位ビットは符号ビットとは解釈されません.
書式
-
result = bge(i, j)
-
i
,j
は整数(1, 2, 4, 8バイト)もしくはBOZリテラル.-
i
,j
のどちらもBOZリテラルであってはならない. -
i
,j
の整数kindは同じでなければならない. -
i
,j
は配列でもよい.
-
-
result
は論理型.-
i
のビット列がj
のビット列より大きいか等しい場合に真,そうでない場合に偽となる. -
i
,j
が配列の場合,result
はi
,j
と同じ次元,要素数の配列.
-
-
例
program main
use, intrinsic :: iso_fortran_env
implicit none
integer(int32) :: i, j
i = int(B'01111111111111111111111111111111')
j = int(B'01111111111111111111111111111110')
print *, bge(i, j) ! T
end program main
program main
use, intrinsic :: iso_fortran_env
implicit none
integer(int32) :: i, j
i = int(B'01111111111111111111111111111111')
j = int(B'01111111111111111111111111111111')
print *, bge(i, j) ! T
end program main
program main
use, intrinsic :: iso_fortran_env
implicit none
integer(int32) :: i, j
i = int(B'00000000000000000000000000000000')
j = int(B'11111111111111111111111111111111')
print *, bge(i, j) ! F
end program main
bgt
二つの整数型変数,整数リテラルあるいはBOZリテラルをビットごとに比較し,ビット列が大きいかを判別した結果を論理値で返します.この比較において,最上位ビットは符号ビットとして解釈されません.
書式
-
result = bgt(i, j)
-
i
,j
は整数(1, 2, 4, 8バイト)もしくはBOZリテラル.-
i
,j
のどちらもBOZリテラルであってはならない. -
i
,j
の整数kindは同じでなければならない. -
i
,j
は配列でもよい.
-
-
result
は論理型.-
i
のビット列がj
のビット列より大きい場合に真,そうでない場合に偽となる. -
i
,j
が配列の場合,result
はi
,j
と同じ次元,要素数の配列.
-
-
例
program main
use, intrinsic :: iso_fortran_env
implicit none
integer(int32) :: i, j
i = int(B'01111111111111111111111111111111')
j = int(B'01111111111111111111111111111110')
print *, bgt(i, j) ! T
end program main
program main
use, intrinsic :: iso_fortran_env
implicit none
integer(int32) :: i, j
i = int(B'01111111111111111111111111111111')
j = int(B'01111111111111111111111111111111')
print *, bgt(i, j) ! F
end program main
ble
二つの整数型変数,整数リテラルあるいはBOZリテラルをビットごとに比較し,ビット列が小さいか等しいかを判別します.この比較において,最上位ビットは符号ビットとして解釈されません.
書式
-
result = ble(i, j)
-
i
,j
は整数(1, 2, 4, 8バイト)もしくはBOZリテラル.-
i
,j
のどちらもBOZリテラルであってはならない. -
i
,j
の整数kindは同じでなければならない. -
i
,j
は配列でもよい.
-
-
result
は論理型.-
i
のビット列がj
のビット列より小さいか等しい場合に真,そうでない場合に偽となる. -
i
,j
が配列の場合,result
はi
,j
と同じ次元,要素数の配列.
-
-
例
program main
use, intrinsic :: iso_fortran_env
implicit none
integer(int32) :: i, j
i = int(B'01111111111111111111111111111110')
j = int(B'01111111111111111111111111111111')
print *, ble(i, j) ! T
end program main
program main
use, intrinsic :: iso_fortran_env
implicit none
integer(int32) :: i, j
i = int(B'01111111111111111111111111111111')
j = int(B'01111111111111111111111111111111')
print *, ble(i, j) ! T
end program main
program main
use, intrinsic :: iso_fortran_env
implicit none
integer(int32) :: i, j
i = int(B'00000000000000000000000000000000')
j = int(B'11111111111111111111111111111111')
print *, ble(i, j) ! T
end program main
blt
二つの整数型変数,整数リテラルあるいはBOZリテラルをビットごとに比較し,ビット列が小さいかを判別した結果を論理値で返します.この比較において,最上位ビットは符号ビットとして解釈されません.
書式
-
result = ble(i, j)
-
i
,j
は整数(1, 2, 4, 8バイト)もしくはBOZリテラル.-
i
,j
のどちらもBOZリテラルであってはならない. -
i
,j
の整数kindは同じでなければならない. -
i
,j
は配列でもよい.
-
-
result
は論理型.-
i
のビット列がj
のビット列より小さい場合に真,そうでない場合に偽となる. -
i
,j
が配列の場合,result
はi
,j
と同じ次元,要素数の配列.
-
-
例
program main
use, intrinsic :: iso_fortran_env
implicit none
integer(int32) :: i, j
i = int(B'01111111111111111111111111111110')
j = int(B'01111111111111111111111111111111')
print *, blt(i, j) ! T
end program main
program main
use, intrinsic :: iso_fortran_env
implicit none
integer(int32) :: i, j
i = int(B'01111111111111111111111111111111')
j = int(B'01111111111111111111111111111111')
print *, blt(i, j) ! F
end program main
変換・操作
整数をビット単位で操作する手続や,ビット列を他の表現として解釈するような手続を紹介します.
これらの手続きでビットの位置を指定する場合,最下位ビットの位置を0とします.
ibset
整数型変数あるいは整数リテラルの,指定された位置のビットを1に置き換えた値を整数で返します.
書式
-
result = ibset(i, pos)
-
i
は整数(1, 2, 4, 8バイト).-
i
は配列でもよい.
-
-
pos
は整数で,0以上i
のビットサイズ未満の値.-
pos
は配列でもよい. -
i
とpos
の両方を配列とする場合,配列の形状は同じでなければならない.
-
-
result
は整数.- kindは
i
と同じ. -
i
が配列の場合,result
はi
と同じ次元,要素数の配列. -
pos
が配列の場合,result
はpos
と同じ次元,要素数の配列.
- kindは
-
例
program main
use, intrinsic :: iso_fortran_env
implicit none
integer(int8) :: i
i = int(B'00000000', kind=int8)
print '(*(B8.8:," "))', ibset(i, 0) ! 00000001
print '(*(B8.8:," "))', ibset(i, 7) ! 10000000
!
! ibset(i, 0)
!
! ビットを1にする位置
! v
! i 00000000 -> result 00000001
! pos 76543210
end program main
ibclr
整数型変数あるいは整数リテラルの,指定された位置のビットを0に置き換えた値を整数で返します.
書式
-
result = ibclr(i, pos)
-
i
は整数(1, 2, 4, 8バイト).-
i
は配列でもよい.
-
-
pos
は整数で,0以上i
のビットサイズ未満の値.-
pos
は配列でもよい. -
i
とpos
の両方を配列とする場合,配列の形状は同じでなければならない.
-
-
result
は整数.- kindは
i
と同じ. -
i
が配列の場合,result
はi
と同じ次元,要素数の配列. -
pos
が配列の場合,result
はpos
と同じ次元,要素数の配列.
- kindは
-
例
program main
use, intrinsic :: iso_fortran_env
implicit none
integer(int8) :: i
i = int(B'11111111', kind=int8)
print '(*(B8.8:," "))', ibclr(i, 0) ! 11111110
print '(*(B8.8:," "))', ibclr(i, 7) ! 01111111
!
! ibclr(i, 7)
!
! ビットを0にする位置
! v
! i 11111111 -> result 01111111
! pos 76543210
end program main
ibits
整数型変数あるいは整数リテラルの,指定された範囲のビットを取り出して右詰し,残りのビットに0を設定した値を整数で返します.取り出す範囲は,ビットの位置と,その位置から上位桁方向の長さで指定します.
書式
-
result = ibits(i, pos, len)
-
i
は整数(1, 2, 4, 8バイト). -
pos
は整数で,0以上の値.-
pos
+len
はi
のビットサイズ以下.
-
-
len
は整数で,0以上の値.-
pos
+len
はi
のビットサイズ以下.
-
-
result
は整数.- kindは
i
と同じ. -
pos
が配列の場合,result
も配列.
- kindは
-
例
program main
use, intrinsic :: iso_fortran_env
implicit none
integer(int8) :: i
i = int(B'11110000', kind=int8)
print '(*(B8.8:," "))', ibits(i, 2, 4) ! 00001100
!
! ibits(i, 2, 4)
!
! 抜き出すビット
! <--> len 抜き出されたビット
! v pos v--v
! i 11110000 -> result 00001100
! pos 76543210
! ^--^
! 0詰め
end program main
merge_bits
二つの整数変数,整数リテラルあるいはBOZリテラルを一つに併合し,結果を整数として返します.併合のする際にどちらのビットを採用するかは,追加の整数型引数に基づいて決定されます.
簡単に,第3引数のビットが1の位置は第1引数のビットが選ばれ,0の位置は第2引数のビットが選ばれると理解して問題ありません.
書式
-
result = merge_bits(i, j, mask)
-
i
,j
は整数(1, 2, 4, 8バイト)もしくはBOZリテラル.-
i
,j
のどちらもBOZリテラルであってはならない. -
i
,j
の整数kindは同じでなければならない.
-
-
mask
は整数(1, 2, 4, 8バイト).-
mask
の整数kindは,i
,j
と同じでなければならない.
-
-
result
は整数.- kindは
i
と同じ. -
mask
のビットが1の桁ではi
のビット,0の桁ではj
のビットと同じ値.
- kindは
-
例
program main
use, intrinsic :: iso_fortran_env
implicit none
integer(int8) :: i, j, mask
i = int(B'01001101', kind=int8)
j = int(B'10110010', kind=int8)
mask = int(B'11111111', kind=int8)
print '(*(B8.8:," "))', merge_bits(i, j, mask) ! 01001101
end program main
program main
use, intrinsic :: iso_fortran_env
implicit none
integer(int8) :: i, j, mask
i = int(B'01001101', kind=int8)
j = int(B'10110010', kind=int8)
mask = int(B'00000000', kind=int8)
print '(*(B8.8:," "))', merge_bits(i, j, mask) ! 10110010
end program main
program main
use, intrinsic :: iso_fortran_env
implicit none
integer(int8) :: i, j, mask
i = int(B'01001101', kind=int8)
j = int(B'10110010', kind=int8)
mask = int(B'11110000', kind=int8)
print '(*(B8.8:," "))', merge_bits(i, j, mask) ! 01000010
end program main
mvbits
整数型変数あるいは整数リテラル内の,指定した範囲のビットを他の整数型変数にコピーします.
書式
-
call mvbits(from, frompos, len, to, topos)
-
from
は整数(1, 2, 4, 8バイト). -
frompos
は整数で,0以上の値.-
frompos
+len
はfrom
のビットサイズ以下.
-
-
len
は整数で,0以上の値-
frompos
+len
はfrom
のビットサイズ以下.
-
-
to
は整数型変数.- kindは
from
と同じ. -
to
の値は,元々保持していたビット列に,from
のfrompos
桁から上位ビットの方向に長さlen
のビット列を,topos
の位置に上書きした値となる.
- kindは
-
topos
は整数で,0以上の値.-
topos
+len
はto
のビットサイズ以下.
-
-
例
program main
use, intrinsic :: iso_fortran_env
implicit none
integer(int8) :: from, to
from = int(B'00001111', kind=int8)
to = int(B'11100001', kind=int8)
call mvbits(from, 2, 4, to, 3)
print '(*(B8.8:," "))', to ! 10011001
!
! call mvbits(from, frompos, len, to, topos)
!
! 抜き出されたビットが設定される
! <--> len 0011
! v frompos v topos
! from 00001111 to 11100001 -> 10011001
! pos 76543210 76543210
!
end program main
transfar
ビット列を他の表現として解釈します.
書式
-
result = transfer(source, mold[, size])
-
source
は任意の型の変数あるいはリテラル.-
source
はスカラでも配列でもよい.
-
-
mold
は任意の型の変数あるいはリテラル.-
mold
はsource
を解釈するための手本として用いられる. -
mold
はスカラでも配列でもよい.
-
-
size
は整数型.-
size
が省略され,mold
がスカラの場合,result
はスカラ. -
size
が省略され,mold
が配列の場合,result
は1次元配列. -
size
が指定されると,result
は大きさがsize
の1次元配列.
-
-
result
はmold
と同じ型で,source
と同じビット列を持つ.- スカラか配列かは,
mold
およびsize
の指定で決まる.
- スカラか配列かは,
-
例
program main
use, intrinsic :: iso_fortran_env
implicit none
integer(int32) :: i
real(real32) :: r
r = 1.0
i = transfer(r, mold=i) ! 単精度浮動小数点の1.0を表現するビット列を整数に変換する.
print '(B32.32," ",B32.32)', i, r ! 00111111100000000000000000000000 00111111100000000000000000000000 ! NAG Fortranでは,実数に対してB型編集記述子が適用できないため,エラーが出る
print *, i, r ! 1065353216 1.00000000
! 1.0の一つ隣の単精度浮動小数点の値を計算する
r = transfer(i + 1, mold=r)
print *, r, spacing(1.0) ! 1.00000012 1.19209290E-07
end program main
特性値のしゅとく
ビット表現に関係する値を取得する手続を紹介します.
storage_size
引数の変数が占有するメモリサイズをビット単位で返します,
書式
-
result = storage_size(a[, kind])
-
a
は任意の型の実体. -
kind
は整数kindを表す整数. -
result
は整数で,単位は[bit].- kindが省略された場合,
result
のkindはinteger
型のkindと同じ.
- kindが省略された場合,
-
例
program main
use, intrinsic :: iso_fortran_env
implicit none
print *, storage_size(0_int8) ! 8
print *, storage_size(0_int16) ! 16
print *, storage_size(0_int32) ! 32
print *, storage_size(0_int64) ! 64
end program main
bit_size
整数型変数あるいは整数リテラルのビット数を返します.
書式
-
result = bit_size(i)
-
i
は整数(1, 2, 4, 8バイト). -
result
はi
のビット数.-
result
のkindはi
のkindと同じ.
-
-
例
use, intrinsic :: iso_fortran_env
implicit none
print *, bit_size(0_int8) ! 8
print *, bit_size(0_int16) ! 16
print *, bit_size(0_int32) ! 32
print *, bit_size(0_int64) ! 64
end program main
btest
整数型変数,整数リテラルにおいて,指定した桁のビットが1か否かを検査し,結果を論理型で返します.
書式
-
result = btest(i, pos)
-
i
は整数(1, 2, 4, 8バイト).-
i
は配列でもよい.
-
-
pos
は整数で,0以上i
のビット数以下の値.-
pos
は配列でもよい. -
i
とpos
の両方を配列とする場合,配列の形状は同じでなければならない.
-
-
result
は論理型.-
i
のpos
桁目のビットが1の場合は真,0の場合は偽. -
i
が配列の場合,result
はi
と同じ次元,要素数の配列. -
pos
が配列の場合,result
はpos
と同じ次元,要素数の配列.
-
-
例
program main
use, intrinsic :: iso_fortran_env
implicit none
integer(int8) :: i
i = int(B'01010101', kind=int8)
print *, btest(i, 0) ! T
print *, btest(i, 1) ! F
end program main
leadz
整数型変数,整数リテラルの中で,1になっている最も上位のピットよりも上位にある0の数を返します.
書式
-
result = leadz(i)
-
i
は整数(1, 2, 4, 8バイト).-
i
は配列でもよい.
-
-
result
は整数-
i
のビットがすべて0の場合,0の個数が得られる(=ビットサイズと等しい). - kindは
integer
型のkindと同じ. -
i
が配列の場合,result
はi
と同じ次元,要素数の配列.
-
-
例
program main
use, intrinsic :: iso_fortran_env
implicit none
integer(int8) :: i
i = int(B'00010100', kind=int8)
print *, leadz(i) ! 3
end program main
trailz
整数型変数あるいは整数リテラル内の,1になっている最も下位のビットよりも下位にある0の数を返します.
書式
-
result = trailz(i)
-
i
は整数(1, 2, 4, 8バイト).-
i
は配列でもよい.
-
-
result
は整数-
i
のビットがすべて0の場合,0の個数が得られる(=ビットサイズと等しい). - kindは
integer
型のkindと同じ. -
i
が配列の場合,result
はi
と同じ次元,要素数の配列.
-
-
例
program main
use, intrinsic :: iso_fortran_env
implicit none
integer(int8) :: i
i = int(B'00010100', kind=int8)
print *, trailz(i) ! 2
end program main
popcnt
整数型変数,整数リテラル内の1となっているビットの数を返します.
書式
-
result = popcnt(i)
-
i
は整数(1, 2, 4, 8バイト).-
i
は配列でもよい.
-
-
result
は整数- kindは
integer
型のkindと同じ. -
i
が配列の場合,result
はi
と同じ次元,要素数の配列.
- kindは
-
例
program main
use, intrinsic :: iso_fortran_env
implicit none
integer(int8) :: i
i = int(B'0101010', kind=int8)
print *, popcnt(i) ! 3
end program main
program main
use, intrinsic :: iso_fortran_env
implicit none
integer(int8) :: i
i = int(B'0111010', kind=int8)
print *, popcnt(i) ! 4
end program main
poppar
整数型変数,整数リテラル内の1となっているビットの数が奇数の場合に1,偶数の場合に0を返します.
書式
-
result = poppar(i)
-
i
は整数(1, 2, 4, 8バイト).-
i
は配列でもよい.
-
-
result
は整数で,0または1.- kindは
integer
型のkindと同じ.
- kindは
-
例
program main
use, intrinsic :: iso_fortran_env
implicit none
integer(int8) :: i
i = int(B'0101010', kind=int8)
print *, poppar(i) ! 1
end program main
program main
use, intrinsic :: iso_fortran_env
implicit none
integer(int8) :: i
i = int(B'0111010', kind=int8)
print *, poppar(i) ! 0
end program main