首页 >

Fortran读取24位数据

作者:fcode  日期:03-15
来源:Fcode研讨团队
Fortran 的数据类型里,整型通常有 8 位(通常 kind=1),16位(通常 kind=2,短整型) ,32 位(通常 kind=4,普通整型),64 位(通常kind=8,长整型)等数据类型。

但没有编译器支持 24 位的整数类型。而有很多数据却恰恰采用了 24 位整型来存储。对于这种数据,我们需要进行一定的技巧和转换来实现读取。

最直接的办法,是通过内存里的延展,使其读取后,延展为 32 位的整型,并在内存中后续参与计算。

程序运行如下,将 e5ac23 这个 24 位数据写入 t.bin,并读出成 2338021


大图

第一步:
为了能利用 stream 流文件读写,我们定义一个大小为 4 的字符数组 str,取其片段 str(1:3) 进行读取,这样就可以保证读取的是 24 位数据。如果您读取的数据是大端(big-endian)的,则更改为 str(3:1:-1) 反向读取即可。

第二步:
利用 transfer 函数,把 str 字符数组,直接转换成 32 位整型 n 。注意 transfer 函数的作用是强制转换,而不是像内部文件转换那样,考虑字符串代表的数字意义。

第三步:
由于 24 位数据,最高位第24位,表示正负。而直接转换成 32 位后,不能再具有正负的意义。因此,我们需要把 24 位数据左移 8 位,可以利用 ishft 函数实现。
左移可以确保正负号归位。但同时会令整型数值的绝对值增加 2**8 倍。因此左移后需要除以 2**8。

如果关于位操作比较难理解。那么也可以理解这句纯数字计算的算式:
if ( n > (2**23-1) ) n = n - 2**24
其含义是:如果 n 的大小超过了 24 位数据正半部分的上限,就令其减少 2**24 。
这样做的原因是 24 位扩展到32位之后,由于高位为零,始终是正数。这相当于把 24 位数据可以表达的范围由 0 至 2**24 更改到 -2**23 至 2**23-1 (这样做的前提是 str(4) = char(0) ,即高位初值为 0)

代码如下:
Program www_fcode_cn
  Implicit None
  Character :: str(4)
  Integer   :: n
  Open( 12 , File = "t.bin" , access='stream' , form='unformatted' )
  Read( 12 ) str(1:3) !//如果是大端,则 str(3:1:-1)
  n = transfer( str , n )
  n = ishft( n , 8  ) / 2**8
! if ( n > (2**23-1) ) n = n - 2**24 !如果上句不容易理解,也可以理解此句代码
  write(*,'(g0)') n
End Program www_fcode_cn
常规|工具|专业|读物|
代码|教学|算法|
首页 >
FortranCoder手机版-导航