我將一箇舊的數學模型(1995年至2000年之間)移植到當前的linux機器上。對於這一點,我適應所有的makefile文件,如下所示:Fortran 77從舊的sun機讀取無格式的序列數據
FORTRAN = gfortran # f90 -f77 -ftrap=%none
OPTS = -O -u -lgfortran -g -fconvert="big-endian" # -O -u
NOOPT =
LOADER = gfortran #f90
LOADOPTS = #-lf77compat
和:
SYSFFLAGS = -O0 -u -g -fconvert="big-endian" # -f77=input
SYSCFLAGS = -DX_WCHAR
SYSLDFLAGS =
SYSCPPFLAGS = -DSYS_UNIX -DCODE_ASCII -DCODE_IEEE # -DSYS_Sun
SYSAUTODBL = -fdefault-real-8 #-r8
SYSDEBUG = -g
SYSCHECK = -C
LINKOPT =
CPPOPT =
SHELL = /bin/sh
CC = cc
FC = gfortran # f90
LD = gfortran # f90
AR = ar vru
RM = rm -f
CP = cp
MV = mv -f
LN = ln -s
所以我更換了所有過時的編譯器/選項能夠編譯代碼。之後,它會生成沒有錯誤的二進制文件。請注意,後面的#符號的所有選項都在Makefiles中的原始選項中。
因此,在運行程序時,不可能讀取樣本數據。 IMO這些文件在Sun機器上創建爲未格式化序列模式。以下十六進制轉儲屬於我需要閱讀的文件。
0000000: 0000 0400 2020 2020 2020 2020 2020 2020 ....
0000010: 3930 3130 7465 7374 2d63 3031 2020 2020 9010test-c01
0000020: 2020 2020 4741 5520 2020 2020 2020 2020 GAU
0000030: 2020 2020 2020 2020 2020 2020 2020 2020
0000040: 2020 2020 2020 2020 2020 2020 2020 2020
0000050: 2020 2020 2020 2020 2020 2020 2020 2020
...
...
0000390: 2020 2020 2020 2020 2020 2020 2020 2020
00003a0: 2020 2020 2020 2020 2020 2020 2020 2020
00003b0: 2020 2020 3139 3936 3037 3232 2032 3030 19960722 200
00003c0: 3434 3920 4147 434d 352e 3420 2020 2020 449 AGCM5.4
00003d0: 2020 2020 3230 3030 3036 3134 2031 3230 20000614 120
00003e0: 3831 3720 6869 726f 2020 2020 2020 2020 817 hiro
00003f0: 2020 2020 2020 2020 2020 2020 2020 2034 4
0000400: 3039 3630 0000 0400 0002 8000 bef7 21f3 0960..........!.
0000410: bf3c 55ab bf7a 8f71 bf99 e26a bfb2 db4e .<U..z.q...j...N
0000420: bfc7 425f bfd6 64b1 bfdf d44f bfe3 6a43 ..B_..d....O..jC
分析代碼之後,就能夠讀取,直到行。在標記之後不可能繼續。下面顯示的源代碼實際上是讀取這個文件。
...
* [INPUT]
INTEGER IFILE
CHARACTER HITEM *(*) !! name for identify
CHARACTER HDFMT *(*) !! data format
*
* [ENTRY INPUT]
REAL * 8 TIME1 !! time
REAL * 8 TIME2 !! time
REAL*8 DMIN
REAL*8 DMAX
REAL*8 DIVS
REAL*8 DIVL
INTEGER ISTYPE
INTEGER JFILE !! output file No.
INTEGER IMAXD
INTEGER JMAXD
*
* [WORK]
REAL * 8 DDATA (NGDWRK)
REAL * 4 SDATA (NGDWRK)
*
* [INTERNAL WORK]
INTEGER I, J, K, IJK, IJKNUM, IERR
...
...
READ (IFILE, IOSTAT=IEOD) HEAD
...
...
...
DO 2150 IJK = 1, IJKNUM
READ (IFILE, END=2150) SDATA(IJK)
WRITE (6,*) ' IGTIO::GTZZRD: iteration=', IJK, SDATA(IJK)
2150 CONTINUE
爲了輕鬆地調試我替換爲上面的循環。原來的是隱含的。
READ (IFILE, IOSTAT=IEOD)
& (SDATA(IJK), IJK=1, IJKNUM)
和輸出的循環是:
IGTIO::GTZZRD: iteration= 1 -0.48268089
IGTIO::GTZZRD: iteration= 2 1.35631564E-19
IGTIO::GTZZRD: iteration= 3 -0.48142704
IGTIO::GTZZRD: iteration= 4 1.35631564E-19
IGTIO::GTZZRD: iteration= 5 244.25270
IGTIO::GTZZRD: iteration= 6 1.35631564E-19
IGTIO::GTZZRD: iteration= 7 983.87988
IGTIO::GTZZRD: iteration= 8 1.35631564E-19
IGTIO::GTZZRD: iteration= 9 1.59284362E-04
IGTIO::GTZZRD: iteration= 10 1.35631564E-19
IGTIO::GTZZRD: iteration= 11 0.0000000
---error here---
我肯定失去了這一點,所以任何幫助表示讚賞。
迭代2,'1.35631564E-19'仍然看起來對我來說是不正確的。至少在一點點。幾個想法探索。你能夠'ntohl'這些迭代。 SDATA的大小是多少,「real * 4」,你可以試試真實的* 8嗎?只是想法,祝你好運。 –
你知道輸出應該是什麼嗎?初始輸出是否正確? Sun可能使用了big-endian,而如果使用英特爾,則Linux將是小端。對於原生格式的文件(Fortran未格式化),重要的是硬件而不是操作系統。轉換endian應該足夠整數。 gfortran有一個endian轉換的選項:http://gcc.gnu.org/onlinedocs/gfortran/CONVERT-specifier.html。浮點數可能不夠,這可能在表示方面有其他差異。 –
@francescalus HEAD長度爲1024(64 * 16) – rgrun