首页 > 解决方案 > 有效性 - 从未格式化的二进制文件读取时检查逻辑值

问题描述

我用 fortran 读取了一个未格式化的二进制检查点文件,需要检查这些值的有效性。检查点的全部意义在于发生了一些崩溃并且检查点文件本身可能已损坏(例如,如果在写入文件期间发生崩溃)。

所以我现在的问题是:是否有一个标准程序来检查从文件中读取的逻辑值是否正确存储为逻辑值。

写任何数字而不是逻辑并阅读它的简短测试给了我一个.false。价值。我假设读取的每个数字都将按照类似 C 的规则进行转换:nr==0 ->.false。nr!=0 -> .true.. 然而,这并不能帮助我辨别逻辑是否正确编写。

我能想象的是首先将值读取为整数(或某种二进制值?)并检查它们是 0 还是 1,指向正确写入逻辑。

例子:

write_test.f90:

program write_test
logical,parameter :: bool=.true.
real*8,parameter :: r=5e20
open(unit=10,form='unformatted')
write(10)bool,r
close(10)
end program

read_test.f90:

program read_test
logical :: bool1
logical :: bool2
open(unit=10,form='unformatted')
read(10)bool1,bool2
write(*,*)bool1,bool2
end program

read_test.f90 的输出:

T F

bool2看起来它是一个很好的逻辑值 .false.,但它被存储为一个真实的,我想避免它以及可能被抛出的所有其他数据类型。

显然它也没有使用.true。对于 0 以外的值。我的猜测是存储在那里的实数的前导位是 0,它只读取这个单个位。

标签: fortranfortran90

解决方案


这可能是扩展评论而不是答案:

当您假设读取的每个数字都将按照类似 C 的规则进行转换时,您就错了:nr==0 ->.false。nr!=0 -> .true。或者至少,Fortran 标准的规则不能保证您的假设是正确的。这对用于表示 True 和 False 的位模式的问题保持沉默,特别是它不要求它们应该与用于表示 0 和 1(或 1 和 0 - 我永远无法得到那些认为那些是布尔值的有趣语言的窍门)。

Fortran 标准所做的几乎所有保证是默认大小的实数、整数和逻辑在内存中占用相同数量的位,并且(除非您摆弄它们)在未格式化的情况下写入文件。这意味着,除其他外,任何 32 位(或 64,如果这是您的默认存储单元大小)都可以解释为实数、整数或逻辑。

某些位模式可能无法成功解释为任何或所有这些类型,但这又是一个低于 Fortran 标准运行级别的实现问题。

仅从位无法知道一组 32 位代表什么类型的值,必须在某处描述如何解释二进制文件。这就是使它们相当不便携的原因。

如果这些问题对您很重要,您真的必须自己调查它们,特别是您的编译器(版本)使用什么位模式来表示逻辑值。您可以合理地期望(尽管这不能保证)整数以二进制补码形式表示,而实数以 IEEE 形式表示。


推荐阅读