参考网址 UNSIGNED INTEGERS - Intel Communities (https://community.intel.com/t5/Intel-Fortran-Compiler/UNSIGNED-INTEGERS/m-p/876899)
一些数据是以无符号整数处理的,而标准的Fortran不支持这种类型的数据定义。尽管一些厂商的Fortran (Sun g95)支持定义unsigned定义无符号整型数,但这个方法并不受到Fortran社区推荐。
在许多情况下,可以使用INTEGER(C_INT)进行替代,其中C_INT是内部模块ISO_C_BINDING(10.0及更高版本)中定义的常量,但不要尝试直接使用它进行无符号运算。通常可以得到所需的结果,但有时需要将无符号数通过ZXET函数(0扩展函数,将输入二进制数的左边(高位)补0)转换为INTEGER(8),然后将其截断为INTEGR(C_INT)。 (注:截断方法,使用IBITS函数)
比如
integer(kind=4) :: ui4bytes!//4字节无符号整型数 integer(kind=8) :: i8bytes !//8字节有符号整型数 integer(kind=4) :: i4bytes !//4字节有符号整型数 !//利用zext函数,将4字节无符号整型数,高位补零,扩展到8字节,结果输出到i8bytes i8bytes = zext(ui4bytes,8) !//利用ibits函数,将8字节有符号整数,截断选取前4个字节(即从第0位开始,截取32位),结果存储到i4bytes i4bytes = ibits(i8bytes,0,32)
!//注意:由于截断,原先超出范围的数据无法正常显示
例子:处理使用unsigned integer 整型 (1个字节):
假设Fortran数组使用 INTEGER, INTEGER(2), INTEGER(4), 和 INTEGER(8),假设数据的值范围是0:255
一个较为直接的办法是,使用INT函数,将较大的数转换到Integer(1)中:
INTEGER :: in(n) INTEGER(1) :: out(n) do i=1,n out(i) = INT(in(i),1) !//即,将其转换成1字节大小的整数 end do
转换回来的方法,进行逻辑与运算IAND
INTEGER(1) :: in(n) INTEGER :: out(n) do i=1,n out(i) = IAND(INT(in(i)),255) end do
IBITS用法
IBITS,截取指定位范围内的位(二进制)序列。用法为RESULT = IBITS(I, POS, LEN)
IBITS从I中提取长度为LEN的字段,从右边往左数(对于字节序为小端Little Endian而言)的第POS位开始(最右边是第0位),向左延伸LEN位。结果右对齐,其余位归零。POS+LEN的值必须小于或等于值BIT_SIZE(I)。
例子1: IBITS(12,1,4) 结果是6
上式意思为,对12这个数,取其二进制的第1位,截取长度为4的数据,返回结果。
说明:对于占4个字节的整型数据,12这个数的二进制为 0000 0000 0000 1100,二进制的第1位,也就是从右往左数的第2个位置(因为最右边是第0位),值是0,截取长度为4的数据,就是‘0110’,然后右对齐,剩余位补充0,结果就是二进制的0000 0000 0000 0110,换算成10进制就是6
例子2: IBITS(10,1,7)的结果是5
10,其二进制为0000 0000 0000 1010,从右边第1位开始值第7位的数是’0000101‘,右对齐,空位补0之后,就是二进制的0000 0000 0000 0101,换算成10进制就是5。
总结:
由于Fortran不支持无符号整型(unsigned integer),所以,对于这些类型的数据,可以将其的高位补0,转换成更高精度的整型。
比如,对于 十进制数(32769),其二进制表示为(1000 0000 0000 0001),如果把它读进integer(2)的变量的话,将其识别成-32767(有符号整型中,负数的值为补码后的相反数,所以将其识别成了-(0111 1111 1111 1111)),
其值超过了Fortran中的短整型integer(kind=2)所表示的范围(-32768~+32767),无法用短整型表示。
但它可以用无符号的整型表示,
数值(二进制) |
unsigned integer 第一位也用来表示大小 |
signed intger(kind=1) 第一位表示符号正负 |
11111111 |
会被识别成255 |
会被识别成 -1 -(00000001) |
01000000 | 64 | +64 |
10000000 | 128 |
会被识别成 -128 -(10000000) |
10000001
|
129 |
会被识别成 -127 -(01111111) |
*负数值为 按位取反+1
注:实际存储情况因字节序而异
后记:
另外,据Fortran语言论坛介绍1,2,Fortran2008标准中推出了BITS这个类型,但是目前的编译器似乎不支持这个语法规范,若想实现BITS类型,需要自行编译这个库https://github.com/fortran-lang/stdlib
1. https://fortran-lang.discourse.group/t/module-for-dealing-with-unsigned-integers-in-standard-fortran/1242
2. https://fortran-lang.discourse.group/t/unsigned-integer-data-type-in-modern-fortran/1285
标签:0000,字节,unsigned,Fortran,整型,INTEGER,integer From: https://www.cnblogs.com/jiangleads/p/17055963.html