Reputation: 3
I read an unformatted, binary checkpoint file with fortran and need to check the values for their validity. The whole point of the checkpointing is that there was some crash and the checkpoint file itself could be corrupted (e.g. if the crash happened during writing the file).
So my question now: Is there is a standard procedure to check if logical values read from a file were stored correctly as logical values.
A short test with writing any number instead of the logical and reading it gave me a .false. value. I assume every number that is read will be converted following the C-like rule: nr==0 ->.false. nr!=0 -> .true.. This is however not helping me to discern if the logical was written correctly.
What I could imagine is reading the value as integer (or some kind of binary value?) first and checking if they are 0 or 1, pointing to a proper writing of the logical.
Example:
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
Output of read_test.f90:
T F
bool2
looks as if it was a nice logical with the value .false., but it was stored as a real, which I would like to avoid as well as all other data-types that might get thrown there.
Apparently it is also not using .true. for a values other than 0. My guess is that the leading bit of the real that is stored there is 0 and it is only reading this single bit.
Upvotes: 0
Views: 452
Reputation: 78354
This is perhaps an extended comment rather than an answer:
You are wrong when you assume every number that is read will be converted following the C-like rule: nr==0 ->.false. nr!=0 -> .true. or at least, your assumption is not guaranteed to be true by the rules of the Fortran standard. This is silent on the issue of the bit patterns used to represent True and False, in particular it does not mandate that they should be the same as the bit patterns used to represent 0 and 1 (or 1 and 0 - I can never get the hang of those funny languages that think those are boolean values).
Just about all that the Fortran standard does guarantee is that default-sized reals, integers and logicals occupy the same number of bits in memory and (unless you fiddle about with them) when written unformatted to file. This means, inter alia, that any 32-bits (or 64 if that is your default storage unit size) can be interpreted as a real, an integer or a logical.
Some of the bit patterns may not be interpreted successfully as any or all of those types, but again that is an implementation issue below the level at which the Fortran standard operates.
It's impossible to know, from the bits alone, what type of value a group of 32 bits represents, there has to be a description somewhere of how to interpret binary files. This is what makes them rather unportable.
If these issues matter to you you really have to investigate them for yourself, in particular, what bit patterns does your compiler (version) use to represent the logical values. You can reasonably expect (though this stops short of a guarantee) that integers are represented in two's complement form and reals in IEEE form.
Upvotes: 1